1

업데이트 : 질문이 다시 작성되어 일부 의견은 더 이상 관련이 없습니다.COLLATION 변경 후 SQL Server에서 INDEX 사용이 중지되었습니다.

표에서 데이터 정렬을 변경 한 후에는 색인 사용에 문제가 있습니다. 스캔이 많이 나타났습니다. 기본 데이터베이스 데이터 정렬은 SQL_Latin1_General_CP1_CI_AS입니다.

IF OBJECT_ID('colltest') > 0 DROP TABLE CollTest; 

CREATE TABLE dbo.CollTest 
(
    cs  CHAR(8) COLLATE SQL_Latin1_General_CP1_CS_AS NOT NULL 
    , ci  CHAR(8) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL 
    , cs_latin CHAR(8) COLLATE Latin1_General_CS_AS NOT NULL 
    , ci_latin CHAR(8) COLLATE Latin1_General_CI_AS NOT NULL 
); 

CREATE INDEX ix_cs ON dbo.CollTest (cs); 

CREATE INDEX ix_ci ON dbo.CollTest (ci); 

CREATE INDEX ix_cs_latin ON dbo.CollTest (cs_latin); 

CREATE INDEX ix_ci_latin ON dbo.CollTest (ci_latin); 

WITH q (n) AS (SELECT 1 
       UNION ALL 
       SELECT 1 
       UNION ALL 
       SELECT 1 
       UNION ALL 
       SELECT 1 
       UNION ALL 
       SELECT 1 
       UNION ALL 
       SELECT 1 
       UNION ALL 
       SELECT 1 
       UNION ALL 
       SELECT 1 
       UNION ALL 
       SELECT 1 
       UNION ALL 
       SELECT 1) 
    , q100 (n) AS (SELECT 1 FROM q a, q b) 
    , q10000 (n) AS (SELECT 1 FROM q100 a, q100 b) 
    , q100000 (n) AS (SELECT 1 FROM q a, q10000 b) 
INSERT INTO dbo.CollTest 
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) step 
    , ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) step 
    , ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) step 
    , ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) step 
    FROM q100000; 

그리고 여기가 다음과 같은 쿼리 계획을 설명은 다음과 같습니다 :

SELECT cs FROM dbo.colltest WHERE cs = CAST('1000000' AS NVARCHAR(MAX)) 
SELECT ci FROM dbo.colltest WHERE ci = CAST('1000000' AS NVARCHAR(MAX)) 
SELECT cs_latin FROM dbo.colltest WHERE cs_latin = CAST('1000000' AS NVARCHAR(MAX)) 
SELECT ci_latin FROM dbo.colltest WHERE ci_latin = CAST('1000000' AS NVARCHAR(MAX)) 

enter image description here

는 그래서 데이터 정렬 다음 SQL_ * 인 경우는 사용을 보여줍니다 이제 예제로 살펴 보자 스캔, 라틴어 *가 검색을 사용하면. 왜 그런가요?

+0

SELECT에는 작은 느낌표가 표시됩니다. 흐름의 어딘가에서 암시 적 유형 변환이 발생했을 가능성이 있습니다. –

+0

정수에서 nvarchar (최대 값)로 변환 할 때 불평합니다. 두 쿼리 모두 동일합니다. –

+0

실행 계획의 첫 번째 사진에는 표시되지 않습니까? 이와 같은 캐스트를 사용하면 색인을 검색하지 않고 검색 할 수 있습니다. –

답변

1

이는 윈도우 부씩 Comparing SQL collations to Windows collations

설명하고, 유니 코드 데이터의 비교 유니 데이터와 동일한 알고리즘을 이용의해 구현된다. ... SQL 데이터 정렬에서 SQL Server는 유니 코드가 아닌 데이터에 대해 다른 비교 의미를 으로 정의합니다.

NVARCHAR은 당신이 NVARCHARVARCHAR 열을 비교할 때 너무 열이 암시 적으로 캐스팅해야 VARCHAR보다 높은 데이터 형식 우선 순위를가집니다.

예 데이터

DECLARE @T TABLE 
(
SQL_CollationVC VARCHAR(1) COLLATE SQL_Latin1_General_CP1_CI_AS, 
Win_CollationVC VARCHAR(1) COLLATE Latin1_General_CS_AS, 
INDEX SQL_CollationVC(SQL_CollationVC), 
INDEX Win_CollationVC(Win_CollationVC) 
); 

INSERT INTO @T 
VALUES 
(N'¹',N'¹'), 
(N'½',N'½'), 
(N'¾',N'¾'), 
(N'0',N'0'), 
(N'1',N'1'); 

쿼리

SELECT Win_CollationVC 
FROM @T 
WHERE Win_CollationVC = N'1' 

dynamic seek을 수행하고 varchar 인덱스에서 검색 가능한 인덱스 범위에 조건을 변환 GetRangeThroughConvert를 호출 할 수 있습니다.

SELECT SQL_CollationVC 
FROM @T 
WHERE SQL_CollationVC = N'1' 

당신은 스캔이 두 결과 ¹1

을 반환

<code>enter image description here</code>

주를 볼 수있는 쿼리

enter image description here

또한이 결과를 참고하십시오

SELECT SQL_CollationVC 
FROM @T 
ORDER BY SQL_CollationVC 

이 열의 색인은 위에서 반환 된 순서대로 저장됩니다.그 인덱스를 찾는 간단한에 술어 SQL_CollationVC = N'1'을 변환 할 수 없습니다 때문에

+-----------------+ 
| SQL_CollationVC | 
+-----------------+ 
| ¹    | 
| ½    | 
| ¾    | 
| 0    | 
| 1    | 
+-----------------+ 

1¹는 인덱스에 서로 옆에 저장되지 않습니다.