Dies ist ein Versuch, die Arbeit von Max Vernon zu verbessern . In seiner Lösung schlägt er vor, 2 Indizes für die Ansicht und ein Statistikobjekt zu verwenden.
Der 1. Index wird geclustert, was tatsächlich erforderlich ist, da im Gegensatz zu einem nicht geclusterten Index für eine Tabelle ein Fehler generiert wird, wenn versucht wird, einen nicht geclusterten Index für die Ansicht zu erstellen, ohne zuvor einen geclusterten Index zu haben.
Der 2. Index ist ein nicht gruppierter Index, der als Index hinter der Abfrage verwendet wird. Im Kommentarbereich seiner Antwort fragte ich, was passieren würde, wenn anstelle eines nicht gruppierten Index ein gruppierter Index verwendet würde.
Die folgende Analyse versucht, diese Frage zu beantworten.
Ich verwende genau denselben Code, außer dass ich keinen nicht gruppierten Index für die Ansicht erstelle.
Ich erstelle auch kein Statistikobjekt. Wenn Sie den folgenden Code mit SQL Server Management Studio (SSMS) eingeben, sollten Sie sich bewusst sein, dass möglicherweise rote, verzerrte Linien angezeigt werden, die wie Fehler aussehen. Dies sind (wahrscheinlich) keine Fehler, sondern ein Problem mit der Intellisense.
Sie können entweder Intellisense deaktivieren oder die Fehler ignorieren und die Befehle ausführen. Sie sollten fehlerfrei vervollständigt werden.
-- 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
Der folgende Ausführungsplan (ohne Sicht / Indexsicht) wird erstellt, nachdem die folgende Abfrage für die Tabelle ausgeführt wurde:
SELECT pv.PersistedViewTest_ID, pv.TestComputedColumn
FROM dbo.PersistedViewTest pv
WHERE pv.TestComputedColumn = CONVERT(INT, 26)
GO
Dies gibt eine Vergleichsbasis. Beachten Sie, dass nach Abschluss der Abfrage ein Statistikobjekt erstellt wurde (_WA_Sys_00000003_1FCDBCEB). Das Statistikobjekt PK_PersistedViewTest wurde beim Erstellen des Clustered Table Index erstellt.
Als Nächstes werden die gefilterte Ansicht und der Clustered-Index für diese Ansicht erstellt:
-- 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
Versuchen wir nun erneut, die Abfrage auszuführen, diesmal jedoch gegen die Ansicht:
SELECT pv.PersistedViewTest_ID, pv.TestComputedColumn
FROM dbo.PersistedViewTest_View pv
WHERE pv.TestComputedColumn = CONVERT(INT, 26)
GO
Der neue Ausführungsplan lautet nun:
Wenn der neue Plan nach dem Hinzufügen der Ansicht und des Clustered-Index für diese Ansicht angenommen werden soll, scheinen die Statistiken darauf hinzudeuten, dass sich die für die Ausführung der Abfrage erforderliche Zeit verdoppelt hat. Beachten Sie außerdem, dass nach der Ausführung der Abfrage kein neues Statistikobjekt zur Unterstützung des neuen Index erstellt wurde, das sich von der Abfrage in der Tabelle unterscheidet.
Der Abfrageplan schlägt weiterhin vor, dass die Erstellung eines nicht gruppierten Indexes zur Verbesserung der Leistung der Abfrage sehr hilfreich ist. Bedeutet dies, dass ein nicht gruppierter Index zur Ansicht hinzugefügt werden muss, bevor die gewünschte Leistungsverbesserung erzielt werden kann? Es gibt noch eine letzte Sache zu versuchen. Ändern Sie die Abfrage, um die Option "WITH NOEXPAND" zu verwenden:
SELECT pv.PersistedViewTest_ID, pv.TestComputedColumn
FROM dbo.PersistedViewTest_View pv WITH (NOEXPAND)
WHERE pv.TestComputedColumn = CONVERT(INT, 26)
GO
Daraus ergibt sich der folgende Abfrageplan:
Dieser Ausführungsplan ähnelt dem, der mit dem in Max Vernons Antwort angegebenen nicht gruppierten Index erstellt wurde. Dies geschieht jedoch mit einem (nicht gruppierten) Index und einem Statistikobjekt weniger.
Es stellt sich heraus, dass die NOEXPAND-Option mit der Express- und der Standardversion von SQL Server verwendet werden muss, um eine indizierte Ansicht ordnungsgemäß zu verwenden. Paul White hat einen ausgezeichneten Artikel , in dem die Vorteile der NOEXPAND-Option erläutert werden. Er empfiehlt außerdem , diese Option in Verbindung mit der Enterprise Edition zu verwenden, um sicherzustellen, dass die von den Ansichtsindizes bereitgestellte Eindeutigkeitsgarantie vom Optimierer verwendet wird.
Die obige Analyse wurde mit der Express Edition von SQL Server 2014 durchgeführt. Ich habe sie auch mit der Developer Edition von SQL Server 2016 ausprobiert. Die NOEXPAND-Option scheint in der Development Edition nicht erforderlich zu sein, um die Leistungssteigerungen zu erzielen, wird jedoch weiterhin empfohlen .
Vor weniger als 5 Monaten hat Microsoft die Entwicklereditionen kostenlos zur Verfügung gestellt . Die Lizenz beschränkt die Verwendung nur auf die Entwicklung, was bedeutet, dass die Datenbank nicht in einer Produktionsumgebung verwendet werden kann. Wenn Sie also speicheroptimierte Tabellen, Verschlüsselung, R usw. testen möchten, gibt es keine lizenzfreie Ausrede mehr. Ich habe es vor ein paar Tagen zusammen mit SQL Server 2014 Express ohne Probleme erfolgreich auf meinem Computer installiert.
WHERE (sintMarketID = 2 AND strType = 'CARD' AND strTier1 LIKE 'GG%')
.