2019년 3월 3일 일요일

Node.js & SQL Server 인덱스 적용 속도 비교

Node.js & SQL Server 인덱스 적용 속도 비교

Tedious Getting Start 마지막 페이지에는 테이블에 500만 row를 생성한 후 인덱스 적용 여부에 따른 속도를 비교하는 예제가 있다.  Microsoft SQL Server의 성능을 테스트 하기 위해 Dummy 데이터를 준비하고 인덱스 적용 여부에 따른 Query 성능을 측정하는 데 유용할 것으로 보인다.

1. SQL Server 데이터 준비하기

다음과 같은 명령을 이용하여 500만 row를 생성한다.

  • sqlcmd -S localhost -U stormboy -P ***** -d mydb01 -t 60000 -Q "WITH a AS (SELECT * FROM (VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9),(10)) AS a(a))
  • SELECT TOP(5000000)
  • ROW_NUMBER() OVER (ORDER BY a.a) AS OrderItemId
  • ,a.a + b.a + c.a + d.a + e.a + f.a + g.a + h.a AS OrderId
  • ,a.a * 10 AS Price
  • ,CONCAT(a.a, N' ', b.a, N' ', c.a, N' ', d.a, N' ', e.a, N' ', f.a, N' ', g.a, N' ', h.a) AS ProductName
  • INTO Table_with_5M_rows
  • FROM a, a AS b, a AS c, a AS d, a AS e, a AS f, a AS g, a AS h;"

500만 row를 생성하는데 몇분이 소요된다.


2. 성능 테스트

성능 테스트를 사용하기 위해 node-uuid 모듈이 추가로 사용된다.  uuid는 RFC4122 UUIDs를 생성하는 도구이다. 
UUID는 Universally Unique Identifier의 약자로 URN이라고도 한다. UUID는 128 bits 길이의 시공간에서 단 한개의 ID를 보장하기 위해 사용된다.

  • npm install node-uuid

홈페이지의 소스 중 config항목은 deprecated 되었으므로 일부 변경하여 다음과 같이 코드를 생성한다.

  • var Connection = require('tedious').Connection;
  • var Request = require('tedious').Request;
  • var uuid = require('node-uuid');
  • var async = require('async');

  • var config = {
  •   server: "localhost",
  •   // If you're on Windows Azure, you will need this:
  •   options: {encrypt: false},
  •   authentication: {
  •     type: "default",
  •     options: {
  •       userName: "stormboy",
  •       password: "*****",
  •   }
  • }
  •  ,options: {
  •    debug: {
  •      packet: true,
  •      data: true,
  •      payload: true,
  •      token: false,
  •      log: true
  •    },
  •    database: 'mydb01',
  •    encrypt: false // for Azure users
  •  }
  • };

  • var connection = new Connection(config);
  • function exec(sql) {
  •     var timerName = "QueryTime";

  •     var request = new Request(sql, function(err) {
  •         if (err) {
  •             console.log(err);
  •         }
  •     });
  •     request.on('doneProc', function(rowCount, more, rows) {
  •         if(!more){
  •             console.timeEnd(timerName);
  •         }
  •     });
  •     request.on('row', function(columns) {
  •         columns.forEach(function(column) {
  •             console.log("Sum: " +  column.value);
  •         });
  •     });
  •         console.time(timerName);
  •     connection.execSql(request);
  • }
  • // Open connection and execute query
  • connection.on('connect', function(err) {
  •     async.waterfall([
  •         function(){
  •             exec('SELECT SUM(Price) FROM Table_with_5M_rows');
  •         },
  •     ]);
  • });


생성된 코드를 실행하면 데이터 베이스를 select한 결과와 처리 속도가 표시된다.

  • PS C:\ubuntu\node\oauth2svr\mssql> node perf01
  • Sum: 50000000
  • QueryTime: 1826.074ms


생성된 테이블에 conlumnstore index를 지정한다.

  • PS C:\ubuntu\node\oauth2svr\mssql> sqlcmd -S localhost -U stormboy -P dnjsrms -d mydb01 -Q "CREATE CLUSTERED COLUMNSTORE INDEX Columnstoreindex ON Table_with_5M_rows;"
  • 메시지 35315, 수준 16, 상태 1, 서버 JUNGWONKUN7-PC\SQLEXPRESS, 줄 1
  • 이 버전의 SQL Server에서는 columnstore 인덱스를 만들 수 없으므로 CREATE INDEX 문이 실패했습니다. 각 SQL Server 버전의 기능 지원에 대한 자세한 내용은 온라인 설명서를 참조하십시오.

SQL Server 2014 Express 에서는 Columnstore index를 지원하지 않는것으로 보인다.
하지만 2016 sp1 부터는 Express에서 지원하는 것으로 blog를 통해 확인할 수 있다.



[참고 사이트]

https://tools.ietf.org/html/rfc4122 (RFC4122 UUID 표준)
https://ko.wikipedia.org/wiki/%EB%B2%94%EC%9A%A9_%EA%B3%A0%EC%9C%A0_%EC%8B%9D%EB%B3%84%EC%9E%90 (범용 고유 식별자)
https://docs.microsoft.com/ko-kr/sql/relational-databases/indexes/columnstore-indexes-described?view=sql-server-2014 (Columnstore Index 가이드)
https://www.sqlshack.com/sql-server-2014-columnstore-index/ (Columnstore index를 사용한 성능개선)
https://m.blog.naver.com/PostView.nhn?blogId=gun0626&logNo=40192874161&proxyReferer=https%3A%2F%2Fwww.google.com%2F (2014 Clustered Columnstore Index 설명)


댓글 없음:

댓글 쓰기