본문 바로가기

개발&새발/DB

대소문자 구분 필터 - MSSQL

기본적으로 MSSQL은 대소문자를 구별하지 않는 기본 정렬순서를 가지고 있다. 즉, 'A', 'a'는 (정렬, 비교, 고유성 비교 등의 작업에서)같은 정렬 순위에 놓이게 된다. 때문에 대소문자 구분을 하여 정렬이 필요한 경우 다음 쿼리와 같이 COLLATE 옵션을 이용한다.

  1. USE Northwind
  2. SELECT CustomerID, CompanyName, Country
  3. FROM dbo.CIstomers
  4. WHERE CustomerID COLLATE Latin1_General_CS_AS = N'ALFKI'

이 쿼리는 인덱스를 타지 못한다. 때문에 실행계획을 통해 확인해 보면은 Table Scan이 이루어 지는 것을 확인할 수 있다. 이유는 CustomerID 칼럼에 정렬순서를 변경하는 조작을 하기 때문에, 필터 조건이 쿼리 최적화 프로그램에 의해  검색인수(SARG)로 인식되지 않기 때문이다.

이 문제를 해결하는 방법이자 이 포스트를 하게 된 포인트는...

위 필터 조건에 대소문자를 구분하지 않는 조건를 추가하면은 정상적인 인덱스를 타고 Table Seek가 이루어 진다는 점이다.

다음과 같이...

  1. USE Northwind
  2. SELECT CustomerID, CompanyName, Country
  3. FROM dbo.Customers
  4. WHERE CustomerID COLLATE Latin1_General_CS_AS = N'ALFKI' AND CustomerID = N'ALFKI'

이유는 다음과 같다.

대소문자를 구별하지 않는 필터 조건은 기본적으로 인덱스를 사용할 수 있다. 그리고 대소문자를 구별하지 않는 필터 조건은 대소문자를 구별하는 필터 조건을 포함하는 상위 집한(superset)으로 동작하기 때문에 대소문자를 구분하지 않는 필터조건을 통해 인덱스를 사용하고 그 다음 대소문자를 구분해 내면은 인덱스를 통한 Table Seek가 가능한 것이다.


위와 같은 방법이 대소문자 구분에만 사용되리라 생각되지 않는다. 해결방법 자체가 MSSQL 동작방식에서 얻어낸 것이므로...

때문에 다른 부분에도 응용이 가능하지 않을까 하는 생각이 든다.



INSIDE MICROSOFT SQL SERVER 2005: T-SQL Programming 참고

이 글은 스프링노트에서 작성되었습니다.