이것은 Max Vernon의 작업 개선을위한 시도 입니다. 그의 솔루션에서는 뷰와 통계 개체에 2 개의 인덱스를 사용하는 것이 좋습니다.
첫 번째 인덱스는 클러스터링되는데, 실제로 테이블에 클러스터되지 않은 인덱스와 달리 뷰에 클러스터되지 않은 인덱스를 만들려고 시도하면 먼저 클러스터 된 인덱스가 없어도 오류가 발생합니다.
두 번째 인덱스는 비 클러스터형 인덱스이며 쿼리 뒤에 인덱스로 사용됩니다. 그의 답변의 의견 섹션에서 클러스터되지 않은 인덱스 대신 클러스터형 인덱스를 사용하면 어떻게 될지 물었습니다.
다음 분석은이 질문에 답하려고합니다.
뷰에서 클러스터되지 않은 인덱스를 생성하지 않는 것을 제외하고는 그의 동일한 코드를 사용하고 있습니다.
또한 통계 개체를 만들지 않습니다. SSMS (SQL Server Management Studio)를 따라 아래 코드를 입력하는 경우 오류처럼 보이는 빨간 구불 구불 한 줄이 나타날 수 있습니다. 이러한 오류는 (아마도) 오류는 아니지만 인텔리전스 관련 문제와 관련이 있습니다.
인텔리전스를 비활성화하거나 오류를 무시하고 명령을 실행할 수 있습니다. 오류없이 완료해야합니다.
-- Create the test table that uses a computed column.
USE tempdb;
CREATE TABLE dbo.PersistedViewTest
(
PersistedViewTest_ID INT NOT NULL
CONSTRAINT PK_PersistedViewTest
PRIMARY KEY CLUSTERED
IDENTITY(1,1)
, SomeData VARCHAR(2000) NOT NULL
, TestComputedColumn AS (PersistedViewTest_ID - 1) PERSISTED
);
GO
-- Insert some test data into the table.
INSERT INTO dbo.PersistedViewTest (SomeData)
SELECT o.name + o1.name + o2.name
FROM sys.objects o
CROSS JOIN sys.objects o1
CROSS JOIN sys.objects o2;
GO
다음 쿼리가 테이블에 대해 실행 된 후 다음 실행 계획 (보기 / 인덱스보기 없음)이 생성됩니다.
SELECT pv.PersistedViewTest_ID, pv.TestComputedColumn
FROM dbo.PersistedViewTest pv
WHERE pv.TestComputedColumn = CONVERT(INT, 26)
GO
이것은 비교할 기준을 제공합니다. 쿼리가 완료된 후 통계 개체 (_WA_Sys_00000003_1FCDBCEB)가 생성되었습니다. 클러스터 된 테이블 인덱스를 만들 때 PK_PersistedViewTest 통계 개체가 생성되었습니다.
다음으로 해당보기에서 필터링 된보기 및 클러스터 된 인덱스가 작성됩니다.
-- Create filtered view on the computed column.
CREATE VIEW dbo.PersistedViewTest_View
WITH SCHEMABINDING
AS
SELECT PersistedViewTest_ID, SomeData, TestComputedColumn
FROM dbo.PersistedViewTest
WHERE TestComputedColumn < CONVERT(INT, 27);
GO
-- Create unique clustered index to persist the values, including the computed column.
CREATE UNIQUE CLUSTERED INDEX IX_PersistedViewTest
ON dbo.PersistedViewTest_View(PersistedViewTest_ID);
GO
이제 쿼리를 다시 실행 해 보겠습니다.
SELECT pv.PersistedViewTest_ID, pv.TestComputedColumn
FROM dbo.PersistedViewTest_View pv
WHERE pv.TestComputedColumn = CONVERT(INT, 26)
GO
새로운 실행 계획은 다음과 같습니다.
새 계획을 믿으려면 해당 뷰에 뷰와 클러스터 된 인덱스를 추가 한 후 쿼리 실행에 필요한 시간이 두 배로 늘어난 것으로 나타납니다. 또한 쿼리가 실행 된 후 새 인덱스를 지원하기 위해 테이블에있는 쿼리와 다른 새 통계 개체가 만들어지지 않았습니다.
쿼리 계획은 비 클러스터형 인덱스를 만드는 것이 쿼리 성능을 향상시키는 데 상당히 도움이 될 것이라고 제안합니다. 그렇다면 원하는 성능 향상을 달성하기 전에 비 클러스터형 인덱스를 뷰에 추가해야합니까? 마지막으로 시도해야 할 것이 있습니다. "WITH NOEXPAND"옵션을 사용하도록 조회를 수정하십시오.
SELECT pv.PersistedViewTest_ID, pv.TestComputedColumn
FROM dbo.PersistedViewTest_View pv WITH (NOEXPAND)
WHERE pv.TestComputedColumn = CONVERT(INT, 26)
GO
결과는 다음과 같은 쿼리 계획입니다.
이 실행 계획은 Max Vernon의 답변에 제공된 비 클러스터형 인덱스로 생성 된 것과 매우 유사합니다. 그러나 이것은 하나의 클러스터되지 않은 인덱스와 하나의 통계 개체로 이루어집니다.
인덱스 된 뷰를 올바르게 사용하려면 NOEXPAND 옵션을 Express 및 표준 버전의 SQL Server와 함께 사용해야합니다. Paul White는 NOEXPAND 옵션 사용의 이점에 대해 설명 하는 훌륭한 기사 를 제공합니다. 또한 옵티마이 저가 뷰 인덱스에서 제공하는 고유성 보장을 보장하기 위해이 옵션을 Enterprise Edition과 함께 사용할 것을 권장 합니다.
위의 분석은 SQL Sever 2014의 익스프레스 에디션으로 수행되었습니다. 또한 SQL Server 2016의 개발자 에디션에서도 시도했습니다. NOEXPAND 옵션은 성능 향상을 위해 개발 에디션에 필요하지 않은 것으로 보이지만 여전히 권장됩니다 .
5 개월 전에 Microsoft는 개발자 에디션을 무료 로 만들었습니다 . 라이센스는 개발 만 사용하도록 제한하므로 프로덕션 환경에서는 데이터베이스를 사용할 수 없습니다. 따라서 메모리 최적화 테이블, 암호화, R 등을 테스트하려는 경우 더 이상 라이센스 없음 변명이 없습니다. 며칠 전에 SQL Server 2014 Express와 함께 문제없이 컴퓨터에 성공적으로 설치했습니다.
WHERE (sintMarketID = 2 AND strType = 'CARD' AND strTier1 LIKE 'GG%')
.