Це спроба вдосконалити роботу Макса Вернона . У своєму рішенні він пропонує використовувати 2 індекси для представлення даних та об’єкта статистики.
1-й індекс є кластеризованим, що фактично потрібно, оскільки на відміну від некластеризованого індексу в таблиці, буде створена помилка, якщо спробу створення некластеризованого індексу в представленні подано без спроби кластерного індексу.
2-й індекс - це некластеризований індекс, який використовується як індекс за запитом. У розділі коментарів у своїй відповіді я запитав, що буде, якщо замість некластеризованого індексу буде використаний кластерний індекс.
Наступний аналіз намагається дати відповідь на це питання.
Я використовую його точно такий же код, за винятком того, що я не створюю некластеризований індекс для подання
Я також не створюю об’єкт статистики. Якщо ви слідуєте за та використовуєте 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
Новий план виконання:
Якщо вірити новому плану, після додавання перегляду та кластеризованого індексу для цього представлення з’являється статистика, яка свідчить про те, що час, необхідний для виконання запиту, тепер подвоївся. Також зауважте, що після запуску запиту не було створено жодного нового об’єкта статистики для підтримки нового індексу, який відрізняється від запиту в таблиці.
План запитів все ще передбачає, що створення некластеризованого індексу було б дуже корисним для підвищення продуктивності запиту. Отже, чи означає це, що перед переглядом потрібно додати некластеризований індекс, перш ніж можна отримати бажане поліпшення продуктивності? Є одне останнє, що потрібно спробувати. Змініть запит, щоб використовувати параметр "З 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%')
хоч.