Это попытка улучшить работу Макса Вернона . В своем решении он предлагает использовать 2 индекса для представления и объект статистики.
1-й индекс является кластеризованным, что на самом деле требуется, поскольку в отличие от некластеризованного индекса в таблице будет сгенерирована ошибка, если будет предпринята попытка создания некластеризованного индекса в представлении без предварительного наличия кластерного индекса.
Второй индекс - это некластеризованный индекс, который используется в качестве индекса за запросом. В разделе комментариев его ответа я спросил, что произойдет, если вместо некластеризованного индекса будет использован кластерный индекс.
Следующий анализ пытается ответить на этот вопрос.
Я использую его точно такой же код, за исключением того, что я не создаю некластеризованный индекс для представления.
Я также не создаю объект статистики. Если вы следите за этим и используете SQL Server Management Studio (SSMS) для ввода приведенного ниже кода, вы должны знать, что вы можете увидеть некоторые красные волнистые линии, которые выглядят как ошибки. Это (вероятно) не ошибки, но они связаны с проблемой intellisense.
Вы можете отключить intellisense или просто игнорировать ошибки и запускать команды. Они должны завершиться без ошибок.
-- 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
Это приводит к следующему плану запроса:
Этот план выполнения выглядит очень похоже на тот, который был создан с некластеризованным индексом, данным в ответе Макса Вернона. Но это делается с одним меньшим (некластеризованным) индексом и одним меньшим объектом статистики.
Оказывается, что для правильного использования индексированного представления необходимо использовать опцию NOEXPAND с экспресс-версиями и стандартными версиями SQL Server. У Пола Уайта есть отличная статья, в которой рассказывается о преимуществах использования опции NOEXPAND. Он также рекомендует использовать эту опцию с корпоративной версией, чтобы оптимизатор использовал гарантию уникальности, предоставляемую индексами представлений.
Приведенный выше анализ был выполнен в экспресс-выпуске SQL Sever 2014. Я также попробовал его в редакции SQL Server 2016 для разработчиков. Похоже, что опция NOEXPAND не требуется в выпуске для разработчиков для достижения прироста производительности, но все же рекомендуется ,
Менее 5 месяцев назад Microsoft выпустила бесплатные версии для разработчиков . Лицензия ограничивает использование только разработкой, что означает, что базу данных нельзя использовать в производственной среде. Итак, если вы пытались проверить оптимизированные для памяти таблицы, шифрование, R и т. Д., То у вас больше нет оправдания отсутствия лицензии. Я успешно установил его на своем компьютере несколько дней назад вместе с SQL Server 2014 Express без проблем.
WHERE (sintMarketID = 2 AND strType = 'CARD' AND strTier1 LIKE 'GG%')
хотя.