나는 단순히 연결된 열로 구성된 테이블에 지속 계산 열을 가지고 있습니다.
CREATE TABLE dbo.T
(
ID INT IDENTITY(1, 1) NOT NULL CONSTRAINT PK_T_ID PRIMARY KEY,
A VARCHAR(20) NOT NULL,
B VARCHAR(20) NOT NULL,
C VARCHAR(20) NOT NULL,
D DATE NULL,
E VARCHAR(20) NULL,
Comp AS A + '-' + B + '-' + C PERSISTED NOT NULL
);
이것은 Comp
고유하지 않으며 D는의 각 조합의 날짜에서 유효 A, B, C
하므로 다음 쿼리를 사용하여 각 종료 날짜를 가져옵니다 A, B, C
(기본적으로 동일한 Comp 값의 다음 시작 날짜).
SELECT t1.ID,
t1.Comp,
t1.D,
D2 = ( SELECT TOP 1 t2.D
FROM dbo.T t2
WHERE t2.Comp = t1.Comp
AND t2.D > t1.D
ORDER BY t2.D
)
FROM dbo.T t1
WHERE t1.D IS NOT NULL -- DON'T CARE ABOUT INACTIVE RECORDS
ORDER BY t1.Comp;
그런 다음이 쿼리 (및 다른 쿼리)를 돕기 위해 계산 열에 인덱스를 추가했습니다.
CREATE NONCLUSTERED INDEX IX_T_Comp_D ON dbo.T (Comp, D) WHERE D IS NOT NULL;
그러나 쿼리 계획은 나를 놀라게했습니다. where 절이 있고을 기준으로 D IS NOT NULL
정렬 Comp
하고 계산 된 열의 인덱스를 사용하여 t1 및 t2를 스캔하는 데 사용할 수있는 인덱스 외부의 열을 참조하지 않는다고 생각했지만 클러스터 된 인덱스를 보았습니다. 주사.
따라서이 인덱스를 사용하여 더 나은 계획을 얻었는지 확인했습니다.
SELECT t1.ID,
t1.Comp,
t1.D,
D2 = ( SELECT TOP 1 t2.D
FROM dbo.T t2
WHERE t2.Comp = t1.Comp
AND t2.D > t1.D
ORDER BY t2.D
)
FROM dbo.T t1 WITH (INDEX (IX_T_Comp_D))
WHERE t1.D IS NOT NULL
ORDER BY t1.Comp;
이 계획은
키 조회가 사용되고 있음을 보여줍니다. 자세한 내용은 다음과 같습니다.
이제 SQL-Server 설명서에 따르면 :
CREATE TABLE 또는 ALTER TABLE 문에서 컬럼이 PERSISTED로 표시되면 결정적이지만 부정확 한 표현식으로 정의 된 계산 컬럼에서 인덱스를 작성할 수 있습니다. 즉, 데이터베이스 엔진은 계산 된 값을 테이블에 저장하고 계산 된 열이 종속 된 다른 열이 업데이트 될 때 해당 값을 업데이트합니다. 데이터베이스 엔진은 열에서 인덱스를 만들 때와 인덱스가 쿼리에서 참조 될 때 이러한 지속 된 값을 사용합니다. 이 옵션을 사용하면 데이터베이스 엔진이 계산 된 열 식을 반환하는 함수, 특히 .NET Framework에서 생성 된 CLR 함수가 결정적이고 정확한지 여부를 정확하게 증명할 수없는 경우 계산 된 열에 대한 인덱스를 만들 수 있습니다.
따라서 문서에서 "데이터베이스 엔진이 계산 된 값을 테이블에 저장하고" 값이 인덱스에 저장되어있는 경우 키를 참조하지 않을 때 A, B 및 C를 가져 오는 이유는 무엇입니까? 전혀 쿼리? 나는 그들이 Comp를 계산하는 데 사용되고 있다고 가정하지만 왜 그럴까요? 또한 쿼리에서 인덱스를 사용할 수는 t2
있지만 인덱스를 사용할 수없는 이유는 t1
무엇입니까?
NB SQL Server 2008에 내 주요 문제가있는 버전이기 때문에 태그를 추가했지만 2012 년에도 같은 동작을합니다.