SQL – Fragen und AntwortenNicht gruppierte Indizes und das Beibehalten von Berechtigungen

Saleem Hakani and Dan Carollo

Nicht gruppierte Indizes und ihre Verwendung

F: Was sind nicht gruppierte Indizes, und welche Vor- und Nachteile gibt es bei ihrer Verwendung?

A: Ein nicht gruppierter Index ähnelt einem Stichwortverzeichnis, wie Sie es in der Regel am Ende eines Buchs finden. Alle im Buch enthaltenen Informationen werden im Stichwortverzeichnis nach Themen aufgeführt, und es sind Zeiger in der Form von Seitenzahlen vorhanden, die den Benutzer an Informationen verweisen, die möglicherweise in verschiedenen Abschnitten des Buchs enthalten sind. Zudem sind die Daten in einem Buchindex nicht in derselben Reihenfolge aufgelistet, wie sie im Text des Buchs erscheinen. Dasselbe gilt für nicht gruppierte Indizes. Wenn ein gruppierter Index für eine Tabelle vorliegt, können Sie angeben, in welcher Reihenfolge die Elemente aufgeführt werden sollen. Ansonsten gibt es keine Möglichkeit, die Reihenfolge definitiv festzulegen.

Außerdem verfügen nicht gruppierte Indizes über zwei Einschränkungen: in den Index können nur 16 Spalten aufgenommen werden, und die maximale Größe des Indexschlüssels darf 900 Byte nicht überschreiten. Was bedeutet das also? Sehen Sie sich an, was geschieht, wenn Sie die folgenden Spalten in der Tabelle „Movie“ aus der MovieList-Beispieldatenbank indizieren möchten: MovieTitle NVarchar(50), DirectorName NVarchar(50), ShortStory NVarchar(400).

Angenommen Sie geben folgende Anweisung zum Erstellen der Tabelle aus:

Use MovieList;
CREATE INDEX Movie_IDX ON Movie(MovieTitle, DirectorName, ShortStory); 

Dies führt zu folgender Fehlermeldung: „Warnung! Die maximale Schlüssellänge beträgt 900 Bytes. Der Movie_IDX-Index hat eine maximale Länge von 1000 Bytes. Bei einigen Kombinationen hoher Werte schlägt der INSERT-/UPDATE-Vorgang fehl.“ Sie erhalten die vorstehende Fehlermeldung da der „nvarchar“-Datentyp 2 Byte für jedes Zeichen nutzt. Ein Index, der die vorstehenden drei Spalten enthält, würde die Größenbegrenzung von 900 Byte überschreiten.

Mit der Veröffentlichung von SQL Server® 2005 haben Sie jetzt die Möglichkeit, dieses Problem durch Hinzufügen der Spalten zur INCLUDE-Klausel zu lösen. Es ist ein sehr nützliches Feature, wenn Sie sowohl Größen- als auch Spalteneinschränkungen überwinden wollen. Dazu führen Sie folgende Anweisung aus:

CREATE INDEX Movie_IDX ON Movie(MovieTitle, DirectorName) INCLUDE (ShortStory);

Beachten Sie, dass das Datenbankmodul beim Verwenden der INCLUDE-Klausel während der Indexerstellung Nicht-Schlüsselspalten beim Berechnen der Anzahl von Indexschlüsselspalten oder der Indexschlüsselgröße nicht in Betracht zieht.

Hilfreiche Informationen zu nicht gruppierten Indizes finden sie in den Artikeln „Nicht gruppierte Indizes“ unter msdn2.microsoft.com/aa174537 und „Verwendung nicht gruppierter Indizes“ unter msdn2.microsoft.com/aa933130. Tipps zum Optimieren von Indizes finden Sie unter sql-server-performance.com/optimizing_indexes.asp.

Beibehalten von Berechtigungsdaten

F: Wie lässt sich der Verlust von Berechtigungen vermeiden, wenn ein Abonnement reinitialisiert wird? Ich hatte schon mehrmals das Problem, dass beim Reinitialisieren eines Snapshots alle gewährten Berechtigungen verloren gehen.

A: Standardmäßig werden alle Objekte in der Abonnementdatenbank gelöscht und bei jeder Reinitialisierung eines Abonnements neu erstellt. Doch es gibt zwei Möglichkeiten zum Behandeln dieses Szenarios.

Erstens können Sie alle Berechtigungen nach dem Reinitialisieren neu anwenden. Wenn Sie Berechtigungen manuell einrichten, sollten Sie ein Skript für die Übertragung aller Objektberechtigungen/Berechtigungen auf Anweisungsebene erstellen und sie separat speichern, sodass sie sofort nach dem Reinitialisieren des Abonnements verwendet werden können.

Zweitens können Sie Ihr Abonnement so konfigurieren, dass beim Reinitialisieren des Abonnements keine Objekte gelöscht werden. Dazu können Sie die gespeicherte Systemprozedur SP_CHANGEARTICLE verwenden, um den Wert von PRE_CREATION_CMD für den Parameter @PROPERTY und den Wert NONE, DELETE oder TRUNCATE für den Parameter @Value zu konfigurieren.

Im Dialogfeld „Artikeleigenschaften“ im Zielobjektabschnitt wählen Sie außerdem Folgendes aus: „Vorhandenes Objekt unverändert beibehalten. Daten löschen. Wenn ein Artikel einen Zeilenfilter aufweist, nur die dem Filter entsprechenden Daten löschen. Alle Daten im vorhanden Objekt abschneiden.“ Probieren Sie dies unbedingt in Ihrer Testumgebung aus. Wenn Sie weitere Unterstützung brauchen, finden Sie in der aktuellen Version der SQL Server-Onlinedokumentation entsprechende Informationen.

Saleem Hakani ist Senior Database Engineer, Senior Problem Engineer und Worldwide Microsoft SQL Server Community Lead mit 14 Jahren Erfahrung im Bereich Datenbanksysteme. Er leitet die externe SQL Server-Communitywebsite sqlcommunity.com und kann unter Saleem@sqlcommunity.com erreicht werden.

Dan Carollo ist Operations Engineer und SQL Server-Datenbankadministrator, der im Windows-Team zur Erforschung und Bekämpfung von Antimalware bei Microsoft tätig ist. Er ist als MCT für SQL Server zertifiziert.

© 2008 Microsoft Corporation und CMP Media, LLC. Alle Rechte vorbehalten. Die nicht genehmigte teilweise oder vollständige Vervielfältigung ist nicht zulässig.