SQL - Indizierte Sichten (indexed views)


Was ist eine indizierte Sicht? Was sind die Anwendungsmöglichkeiten, Vor- und Nachteile? Damit beschäftigen wir uns in diesem Artikel.

 

Anders als bei Tabellen, die physisch auf dem Datenträger abgespeichert sind, fungiert eine Sicht (View) wie eine virtuelle Tabelle. Wir können mit der Sicht zwar arbeiten, wie mit einer Tabelle, sie ist aber nicht in der Datenbank abgespeichert. Wir haben in der Sicht gewissermaßen nur die Abfrage hinterlegt, die stattfinden soll – aber die Sicht kann noch mehr.

Views (Sichten) werden zur Vereinfachung unseres Arbeitsprozesses und nicht zuletzt aus Sicherheitsgründen verwendet. Zum einen kann es eine große Arbeitserleichterung sein, bestimmte und eventuell komplexere, häufig verwendete SELECT-Statements nicht ständig neu schreiben zu müssen, sondern einfach die Sicht abzufragen; zum anderen können wir in der Sicht ganz gezielt nur bestimmte Spalten abfragen und die Sicht zum Sicherheitspuffer zwischen Datenbank und User machen.

Aber während die Sichten uns die Arbeit angenehmer machen, vereinfachen sie die Arbeit für die Datenbank noch lange nicht; die abgefragten Daten sind aktuell, die (eventuell sehr komplexen) SELECT-Statements laufen trotzdem im Hintergrund ab, die entsprechenden Tabellen werden genauso abgefragt, als würden wir ein normales SELECT-Statement schreiben, ohne, dass im Hintergrund eine Performance-Optimierung stattfindet.

Das kann je nach Komplexität dazu führen, dass die Abfrage langsam wird. Um dem gegenzusteuern, können wir auf der View einen eindeutigen gruppierten Index (unique clustered index) erstellen. Damit wird die Abfrage schneller, und auch andere Abfragen können davon profitieren.

Leider gibt es in SQL selten eine grandiose Premiumlösung für alle Fälle, und auch die indizierte Sicht (indexed view) hat ihre Nachteile; auf die kommen wir später noch einmal zu sprechen.

Sehen wir uns einmal an, wie wir eine indizierte Sicht (indexed view) erstellen.

 

Vorab zu beachten, wenn wir eine indizierte Sicht erstellen wollen:

·       Sicht muss deterministisch sein (Näheres dazu in der Microsoft-Dokumentation.)

·       Verwenden von WITH SCHEMABINDING

 

 

Deterministisch meint u.a., dass keine Funktionen in der View enthalten sein dürfen, die jedes Mal ein anderes Ergebnis ausgeben, wie beispielsweise GETDATE(). Versuchen wir, für so eine Sicht einen Index zu erstellen, bekommen wir die Fehlermeldung „Cannot create index on view 'viewname'. The function 'getdate' yields nondeterministic results. Use a deterministic system function, or modify the user-defined function to return deterministic results.

With Schemabinding sorgt u.a. dafür, dass wir nicht eine Tabelle löschen können, die von einer indizierten Sicht abgefragt wird (es wird eine Fehlermeldung ausgegeben). In diesem Fall müsste erst die Sicht, dann erst die Tabelle gelöscht werden.

Haben wir diese Dinge beachtet, ist das Erstellen des Index einfach:

 

CREATE UNIQUE CLUSTERED INDEX IX_IndexName

ON v_Viewname(Spaltenname)

 

Bei größeren Datenmengen können wir damit die Anzahl der gelesenen Seiten drastisch zurückschrauben, und der Index kann eventuell auch anderweitig verwendet werden. Ist der eindeutige gruppierende Index (unique clustered index) erstellt, können auch noch weitere nicht gruppierte (non-clustered) Indizes auf der Sicht erstellt werden.

 

Beim Erstellen der indizierten Sicht gibt es noch einige Stolpersteine. So dürfen zum Beispiel bestimmte TSQL-Elemente nicht enthalten sein, u.a. COUNT, MIN oder MAX, und bestimmte Datentypen dürfen nicht für den Index verwendet werden.

 

Ein Nachteil der indizierten Sicht ist natürlich, dass dieser Index nun auch gewartet werden muss! Wir haben zwar unsere Abfrage schneller gemacht, aber jedes Mal, wenn sich etwas an den beteiligten Tabellen ändert, müssen nicht nur die Indizes der ursprünglichen Tabellen, sondern auch der Index/die Indizes auf der Sicht upgedated werden.

 

Solche und ähnliche Themen besprechen wir auch in unseren Kursen. Inzwischen viel Spaß beim Ausprobieren!

 

 

 

 

 

 

Kommentare sind geschlossen