지금 모두 정적 쿼리로 SP 실행해서 질의하도록 수정하고 있는데
예제의 테이블의 모든 컬럼에는 인덱스가 있다고 치자.
Col1 NVARCHAR(50) NOT NULL 컬럼의 예
SELECT TOP(20) * FROM Table1 WHERE Col1 IS NOT NULL ORDER BY Number DESC
이 질의 처리는...
SELECT TOP(20) * FROM Table1 WHERE Col1 LIKE '%' ORDER BY Number DESC
이 질의의 결과와 비용과 같다.
둘 모두 인덱스 스캔을 한다.
-- ------------------------------------
Col2 NVARCHAR(50) NULL 널 허용 컬럼의 예
SELECT TOP(20) * FROM Table1 ORDER BY Number DESC
이 질의의 처리는 WHERE 절이 없고, 인덱스 스캔을 한다.
SELECT TOP(20) * FROM Table1 IsNull(Table1.Col2, '') LIKE '%'
이 질의의 결과는 위와 동일하나, 테이블 스캔을 한다.
처리 시간은 수 천 개의 데이터 테스트로는 약 1ms 차이다.
-- ------------------------------------
궁금한 점이
동적 쿼리 안 쓰고, 모두 정적 쿼리로 수정하면서
WHERE 대상 컬럼이 한 두개뿐이라면 큰 고민 없지만
모든 컬럼이 검색 대상, 즉 WHERE절에 컬럼이 1개만 들어갈 때도, 10개가 들어갈 때도 있다는 것이지.
이게 정적으로 모두 분기 처리하자면 쿼리문이 길어지는 것은 물론이고 너무 복잡해지니 관리가 안될테니
WHERE Col1 LIKE @qp1 + '%' AND Col2 LIKE @qp2 + '%' AND Col3 LIKE @qp3 + '%'
AND IsNull(Table1.NullableCol4, '') LIKE @qp4 + '%'
이렇게 줄여서 처리를 하려고 해.
비용은 수 천 개의 데이터에서 테스트해보면 WHERE절 내에 IsNull 들어가면 1ms ~ 2ms 정도 늘어나던데
이게 나중에 비용이 많이 커질까? 그냥 쓸만한 비용이 될까? 이게 감이 안 옴.
천만 개 정도에서도 10ms 이하의 차이라면 쿼리문 졸라 줄어드니까 그냥 이렇게 편하게 짜고 싶은데...
하나 하나 컬럼 수와 검색할 컬럼의 수에 따라서 분기할 생각하면 GG임...
대량 샘플로 테스트해보려고 SQL 공식 샘플 데이터 다운로드 받고는 있는데
혹시 좋은 팁이 있을까 싶어서 질문함.
자문자답. WHERE절에서의 혹시나 싶었던 IsNull 퍼포먼스가 엄청 심각하다. 약 200만개의 행이 있을 때, 페이징 처리해서 10페이지 정도만 찾아도 SSD, 8코어에서 처리시간이 3000ms, CPU 18000ms 정도나 걸린다.
Nullable 컬럼들을 모두 Not Null로 바꾸고 디폴트값으로 '' Empty로 설정하고 다시 질의하면 처리시간이 0ms 정도 나온다.
퍼포먼스는 이 정도면 괜찮은데, 문제는 Null 컬럼을 안 쓰게 되니 PK-FK 참조 설정을 할 수가 없네....
반드시 값을 얻을 수 없는 컬럼이라 Null이 필요한 건데, 값이 들어갈 때는 PK-FK 참조 제약이 있고, 그런데 Null 불허이니 Empty 값 때문에 참조 제약을 해제해야 하나?