Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Wann gruppierte oder nicht gruppierte Indizes in SQL Server verwendet werden sollten

Datenbankindizes werden verwendet, um die Geschwindigkeit von Datenbankoperationen in einer Tabelle mit einer großen Anzahl von Datensätzen zu verbessern. Datenbankindizes (sowohl Clustered-Indizes als auch Non-Clustered-Indizes) sind Buchindizes in ihrer Funktionalität ziemlich ähnlich. Ein Buchindex ermöglicht es Ihnen, direkt zu den verschiedenen Themen zu gelangen, die im Buch behandelt werden. Wenn Sie nach einem bestimmten Thema suchen möchten, gehen Sie einfach zum Index, finden Sie die Seitennummer, die das gesuchte Thema enthält, und können Sie dann direkt zu dieser Seite gehen. Ohne Index müssten Sie das ganze Buch durchsuchen.

Datenbankindizes funktionieren auf die gleiche Weise. Ohne Indizes müssten Sie die gesamte Tabelle durchsuchen, um eine bestimmte Datenbankoperation auszuführen. Mit Indizes müssen Sie nicht alle Tabelleneinträge durchsuchen. Der Index verweist Sie direkt auf den Datensatz, nach dem Sie suchen, wodurch die Ausführungszeit Ihrer Abfrage erheblich verkürzt wird.

SQL Server-Indizes können in zwei Haupttypen unterteilt werden:

  1. Clusterte Indizes
  2. Nicht gruppierte Indizes

In diesem Artikel werden wir uns ansehen, was Clustered- und Non-Clustered-Indizes sind, wie sie erstellt werden und was die Hauptunterschiede zwischen den beiden sind. Wir werden uns auch ansehen, wann gruppierte oder nicht gruppierte Indizes in SQL Server verwendet werden.

Beginnen wir zunächst mit einem Clustered-Index.

Cluster-Index

Ein Clustered-Index ist ein Index, der die physische Reihenfolge definiert, in der Tabellendatensätze in einer Datenbank gespeichert werden. Da Datensätze nur auf eine Weise physisch in einer Datenbanktabelle gespeichert werden können, kann es nur einen Clustered-Index pro Tabelle geben. Standardmäßig wird ein gruppierter Index für eine Primärschlüsselspalte erstellt.

Standard-Clustered-Indizes

Lassen Sie uns eine Dummy-Tabelle mit einer Primärschlüsselspalte erstellen, um den standardmäßigen gruppierten Index anzuzeigen. Führen Sie das folgende Skript aus:

CREATE DATABASE Hospital

CREATE TABLE Patients
(
id INT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
gender VARCHAR(50) NOT NULL,
age INT NOT NULL
)

Das obige Skript erstellt eine Dummy-Datenbank Hospital. Die Datenbank hat 4 Spalten:ID, Name, Geschlecht, Alter. Die ID-Spalte ist die Primärschlüsselspalte. Wenn das obige Skript ausgeführt wird, wird automatisch ein gruppierter Index für die ID-Spalte erstellt. Um alle Indizes in einer Tabelle anzuzeigen, können Sie die gespeicherte Prozedur „sp_helpindex“ verwenden.

USE Hospital
EXECUTE sp_helpindex Patients

Hier ist die Ausgabe:

Sie können den Indexnamen, die Beschreibung und die Spalte sehen, für die der Index erstellt wurde. Wenn Sie der Patiententabelle einen neuen Datensatz hinzufügen, wird dieser in aufsteigender Reihenfolge des Werts in der ID-Spalte gespeichert. Wenn der erste Datensatz, den Sie in die Tabelle einfügen, eine ID von drei hat, wird der Datensatz in der dritten Zeile statt in der ersten Zeile gespeichert, da der gruppierte Index die physische Reihenfolge beibehält.

Benutzerdefinierte gruppierte Indizes

Sie können Ihre eigenen gruppierten Indizes erstellen. Bevor Sie dies tun können, müssen Sie jedoch den vorhandenen gruppierten Index erstellen. Wir haben einen gruppierten Index aufgrund der Primärschlüsselspalte. Wenn wir die Primärschlüsseleinschränkung entfernen, wird der Standardcluster entfernt. Das folgende Skript entfernt die Primärschlüsseleinschränkung.

USE Hospital
ALTER TABLE Patients
DROP CONSTRAINT PK__Patients__3213E83F3DFAFAAD
GO

Das folgende Skript erstellt einen benutzerdefinierten Index „IX_tblPatient_Age“ für die Altersspalte der Patiententabelle. Aufgrund dieses Indexes werden alle Datensätze in der Patiententabelle in aufsteigender Reihenfolge des Alters gespeichert.


use Hospital
CREATE CLUSTERED INDEX IX_tblPatient_Age
ON Patients(age ASC)

Lassen Sie uns nun ein paar Dummy-Datensätze in die Patiententabelle einfügen, um zu sehen, ob sie tatsächlich in aufsteigender Altersreihenfolge eingefügt werden:

USE Hospital

INSERT INTO Patients

VALUES
(1, 'Sara', 'Female', 34),
(2, 'Jon', 'Male', 20),
(3, 'Mike', 'Male', 54),
(4, 'Ana', 'Female', 10),
(5, 'Nick', 'Female', 29)

Im obigen Skript fügen wir 5 Dummy-Datensätze hinzu. Beachten Sie die Werte für die Altersspalte. Sie haben zufällige Werte und sind in keiner logischen Reihenfolge. Da wir jedoch einen gruppierten Index erstellt haben, werden die Datensätze tatsächlich in aufsteigender Reihenfolge des Werts in der Altersspalte eingefügt. Sie können dies überprüfen, indem Sie alle Datensätze aus der Patiententabelle auswählen.

SELECT * FROM Patients

Hier ist die Ausgabe:

Sie können sehen, dass die Datensätze in aufsteigender Reihenfolge der Werte in der Altersspalte angeordnet sind.

Nicht gruppierte Indizes

Ein nicht gruppierter Index wird auch verwendet, um Suchoperationen zu beschleunigen. Im Gegensatz zu einem Clustered-Index definiert ein Non-Clustered-Index nicht physisch die Reihenfolge, in der Datensätze in eine Tabelle eingefügt werden. Tatsächlich wird ein nicht gruppierter Index an einem anderen Ort als der Datentabelle gespeichert. Ein nicht gruppierter Index ist wie ein Buchindex, der sich getrennt vom Hauptinhalt des Buches befindet. Da sich Non-Clustered-Indizes an einem anderen Ort befinden, kann es mehrere Non-Clustered-Indizes pro Tabelle geben.

Um einen nicht gruppierten Index zu erstellen, müssen Sie die Anweisung „CREATE NONCLUSTERED“ verwenden. Der Rest der Syntax bleibt mit der Syntax zum Erstellen eines gruppierten Indexes identisch. Das folgende Skript erstellt einen nicht gruppierten Index „IX_tblPatient_Name“, der die Datensätze in aufsteigender Reihenfolge des Namens sortiert.

use Hospital
CREATE NONCLUSTERED INDEX IX_tblPatient_Name
ON Patients(name ASC)

Das obige Skript erstellt einen Index, der die Namen der Patienten und die Adresse ihrer entsprechenden Datensätze enthält, wie unten gezeigt:

Name Adresse aufzeichnen
Ana Adresse aufzeichnen
Jon Adresse aufzeichnen
Mike Adresse aufzeichnen
Nick Adresse aufzeichnen
Sara Adresse aufzeichnen

Hier ist die „Datensatzadresse“ in jeder Zeile der Verweis auf die tatsächlichen Tabellendatensätze für die Patienten mit den entsprechenden Namen.

Wenn Sie beispielsweise Alter und Geschlecht des Patienten namens „Mike“ abrufen möchten, sucht die Datenbank zuerst „Mick“ im nicht gruppierten Index „IX_tblPatient_Name“ und ruft aus dem nicht gruppierten Index die tatsächliche Datensatzreferenz ab und wird dies verwenden, um das tatsächliche Alter und Geschlecht des Patienten mit dem Namen „Mike“ zurückzugeben

Da eine Datenbank zwei Suchen durchführen muss, zuerst im nicht gruppierten Index und dann in der eigentlichen Tabelle, können nicht gruppierte Indizes für Suchvorgänge langsamer sein. Bei INSERT- und UPDATE-Operationen sind Non-Clustered-Indizes jedoch schneller, da die Reihenfolge der Datensätze nur im Index und nicht in der eigentlichen Tabelle aktualisiert werden muss.

Wann geclusterte oder nicht geclusterte Indizes verwendet werden sollten

Nachdem Sie nun die Unterschiede zwischen einem geclusterten und einem nicht geclusterten Index kennen, sehen wir uns die verschiedenen Szenarien für die Verwendung der einzelnen Indizes an.

1. Anzahl der Indizes

Das ist ziemlich offensichtlich. Wenn Sie mehrere Indizes für Ihre Datenbank erstellen müssen, entscheiden Sie sich für einen nicht gruppierten Index, da es nur einen gruppierten Index geben kann.

2. SELECT-Operationen

Wenn Sie nur den Indexwert auswählen möchten, der zum Erstellen und Indizieren verwendet wird, sind nicht gruppierte Indizes schneller. Wenn Sie beispielsweise einen Index für die Spalte „Name“ erstellt haben und nur den Namen auswählen möchten, geben nicht geclusterte Indizes den Namen schnell zurück.

Wenn Sie jedoch andere Spaltenwerte wie Alter, Geschlecht über den Namensindex auswählen möchten, wird die SELECT-Operation langsamer, da zuerst der Name aus dem Index gesucht wird und dann die Referenz auf den eigentlichen Tabellendatensatz für die Suche verwendet wird das Alter und das Geschlecht.

Andererseits ist bei Clustered-Indizes, da alle Datensätze bereits sortiert sind, die SELECT-Operation schneller, wenn die Daten aus anderen Spalten als der Spalte mit Clustered-Index ausgewählt werden.

3. INSERT/UPDATE-Operationen

Die INSERT- und UPDATE-Operationen sind mit Non-Clustered-Indizes schneller, da die eigentlichen Datensätze nicht sortiert werden müssen, wenn eine INSERT- oder UPDATE-Operation ausgeführt wird. Vielmehr muss nur der nicht gruppierte Index aktualisiert werden.

4. Speicherplatz

Da Non-Clustered-Indizes an einem anderen Ort als die ursprüngliche Tabelle gespeichert werden, verbrauchen Non-Clustered-Indizes zusätzlichen Speicherplatz. Wenn der Speicherplatz ein Problem darstellt, verwenden Sie einen gruppierten Index.

5. Endgültiges Urteil

Als Faustregel gilt, dass jede Tabelle mindestens einen gruppierten Index haben sollte, vorzugsweise auf der Spalte, die zum Auswählen von Datensätzen verwendet wird und eindeutige Werte enthält. Die Primärschlüsselspalte ist ein idealer Kandidat für einen gruppierten Index.

Andererseits sollten Spalten, die oft in INSERT- und UPDATE-Abfragen involviert sind, einen nicht gruppierten Index haben, vorausgesetzt, dass der Speicherplatz keine Rolle spielt.