SQL-Primärschlüssel und -Index


106

Angenommen, ich habe eine ID-Zeile (int) in einer Datenbank als Primärschlüssel festgelegt. Wenn ich die ID häufig abfrage, muss ich sie auch indizieren? Oder bedeutet es als Primärschlüssel, dass er bereits indiziert ist?

Der Grund, den ich frage, ist, dass ich in MS SQL Server einen Index für diese ID erstellen kann, der, wie angegeben, mein Primärschlüssel ist.

Bearbeiten: eine zusätzliche Frage - schadet es, den Primärschlüssel zusätzlich zu indizieren?

Antworten:


72

Sie haben Recht, es ist verwirrend, dass Sie mit SQL Server doppelte Indizes für dieselben Felder erstellen können. Die Tatsache, dass Sie einen anderen erstellen können, bedeutet jedoch nicht, dass der PK-Index noch nicht vorhanden ist.

Der zusätzliche Index nützt nichts, aber der einzige Schaden (sehr gering) ist die zusätzliche Dateigröße und der Aufwand für die Zeilenerstellung.


39
Der Schaden nicht verwendeter Indizes ist in der Tat sehr schädlich. Zum einen verbrauchen Indizes Speicherplatz. Zum anderen verlangsamt es Schreibvorgänge und Aktualisierungen. Löschen Sie immer Indizes, die nicht verwendet werden sollen.
Pacerier

50

Wie alle anderen bereits gesagt haben, werden Primärschlüssel automatisch indiziert.

Das Erstellen weiterer Indizes für die Primärschlüsselspalte ist nur dann sinnvoll, wenn Sie eine Abfrage optimieren müssen, die den Primärschlüssel und einige andere spezifische Spalten verwendet. Indem Sie einen weiteren Index für die Primärschlüsselspalte erstellen und einige andere Spalten hinzufügen, können Sie die gewünschte Optimierung für eine Abfrage erreichen.

Sie haben beispielsweise eine Tabelle mit vielen Spalten, fragen jedoch nur die Spalten ID, Name und Adresse ab. Mit der ID als Primärschlüssel können wir den folgenden Index erstellen, der auf der ID basiert, jedoch die Spalten Name und Adresse enthält.

CREATE NONCLUSTERED INDEX MyIndex
ON MyTable(ID)
INCLUDE (Name, Address)

Wenn Sie diese Abfrage verwenden:

SELECT ID, Name, Address FROM MyTable WHERE ID > 1000

SQL Server gibt das Ergebnis nur anhand des von Ihnen erstellten Index aus und liest nichts aus der tatsächlichen Tabelle.


28

HINWEIS: Diese Antwort Adressen der Enterprise-Klasse Entwicklung in-the-large .

Dies ist ein RDBMS-Problem, nicht nur SQL Server, und das Verhalten kann sehr interessant sein. Zum einen ist es üblich, dass Primärschlüssel automatisch (eindeutig) indiziert werden, aber NICHT absolut. Es gibt Zeiten, in denen es wichtig ist, dass ein Primärschlüssel NICHT eindeutig indiziert wird.

In den meisten RDBMS wird automatisch ein eindeutiger Index für einen Primärschlüssel erstellt, sofern noch keiner vorhanden ist . Daher können Sie einen eigenen Index für die Primärschlüsselspalte erstellen, bevor Sie ihn als Primärschlüssel deklarieren. Dieser Index wird dann (falls akzeptabel) vom Datenbankmodul verwendet, wenn Sie die Primärschlüsseldeklaration anwenden. Oft können Sie den Primärschlüssel erstellen und zulassen, dass sein eindeutiger Standardindex erstellt wird. Erstellen Sie dann Ihren eigenen alternativen Index für diese Spalte und löschen Sie den Standardindex.

Nun zum lustigen Teil - wann möchten Sie KEINEN eindeutigen Primärschlüsselindex? Sie möchten keine und können keine tolerieren, wenn Ihre Tabelle genügend Daten (Zeilen) erfasst, um die Pflege des Index zu teuer zu machen. Dies hängt von der Hardware, der RDBMS-Engine, den Eigenschaften der Tabelle und der Datenbank sowie der Systemlast ab. Es beginnt sich jedoch normalerweise zu manifestieren, sobald eine Tabelle einige Millionen Zeilen erreicht.

Das wesentliche Problem besteht darin, dass jede Einfügung einer Zeile oder Aktualisierung der Primärschlüsselspalte zu einem Index-Scan führt, um die Eindeutigkeit sicherzustellen. Dieser eindeutige Index-Scan (oder dessen Äquivalent in jedem RDBMS) wird mit zunehmendem Wachstum der Tabelle viel teurer, bis er die Leistung der Tabelle dominiert.

Ich habe dieses Problem viele Male mit Tabellen behandelt, die zwei Milliarden Zeilen, 8 TB Speicher und vierzig Millionen Zeileneinfügungen pro Tag umfassen. Ich wurde beauftragt, das betreffende System neu zu gestalten, wobei der eindeutige Primärschlüsselindex praktisch als erster Schritt gelöscht wurde. In der Tat war es notwendig, diesen Index in der Produktion zu löschen, um sich von einem Ausfall zu erholen, bevor wir uns überhaupt einer Neugestaltung näherten. Diese Neugestaltung beinhaltete die Suche nach anderen Möglichkeiten, um die Eindeutigkeit des Primärschlüssels sicherzustellen und einen schnellen Zugriff auf die Daten zu ermöglichen.


Was ist, wenn der Schlüssel ein Int- oder Bigint-Autoincrement-Schlüssel ist? Ist SQL Server intelligent genug, um in diesem Fall keinen eindeutigen Index-Scan durchzuführen?
Federbrecher

1
@quillbreaker: Es IDENTITYist nicht garantiert, dass ein Feld eindeutig ist. Schließlich können Benutzer doppelte Werte einfügen, wenn sie Benutzer sind IDENTITY_INSERT.

Ich weiß, dass dies ein uraltes Thema ist, aber ich verstehe nicht, wie ein Eindeutigkeitsscan eines Index das System so stark belasten würde. Ein B + -Baum-Scan sollte O (log n) * v sein, wobei v der Overhead für Indexfragmentierung, unvollständiges Baumgleichgewicht usw. beschränkt ist. Somit wären 2 Milliarden Zeilen eine Protokollbasis 2 von 2.000.000.000 (ungefähr 31 Suchvorgängen), z. 2 oder 3 oder sogar 10. 40 Millionen Einsätze pro Tag sind ungefähr 462 / s, ~ 100 E / A pro Einsatz ... Ahh ... Oh. Aha. Und das war vor weit verbreiteten SSDs.
Charles Burns

Wäre der Aufwand für die Überprüfung jeder Zeile auf Eindeutigkeit nicht viel größer, wenn Sie die Eindeutigkeitsbeschränkung nicht aufheben würden?
Max Candocia

20

Primärschlüssel werden standardmäßig immer indiziert.

Sie können einen Primärschlüssel in SQL Server 2012 mithilfe von SQL Server Management Studio oder Transact-SQL definieren. Durch das Erstellen eines Primärschlüssels wird automatisch ein entsprechender eindeutiger, gruppierter oder nicht gruppierter Index erstellt.

http://technet.microsoft.com/en-us/library/ms189039.aspx


9

Hier die Passage aus dem MSDN :

Wenn Sie eine PRIMARY KEY-Einschränkung für eine Tabelle angeben, erzwingt das Datenbankmodul die Eindeutigkeit von Daten, indem ein eindeutiger Index für die Primärschlüsselspalten erstellt wird. Dieser Index ermöglicht auch einen schnellen Zugriff auf Daten, wenn der Primärschlüssel in Abfragen verwendet wird. Daher müssen die ausgewählten Primärschlüssel den Regeln zum Erstellen eindeutiger Indizes entsprechen.


8

Eine PK wird zu einem Clustered-Index, sofern Sie nicht Nonclustered angeben


3

Durch das Deklarieren einer PRIMARY KEYoder einer UNIQUEEinschränkung erstellt SQL Server automatisch einen Index.

Ein eindeutiger Index kann ohne Übereinstimmung mit einer Einschränkung erstellt werden, aber eine Einschränkung (entweder Primärschlüssel oder eindeutig) kann nicht ohne einen eindeutigen Index vorhanden sein.

Von hier aus wird die Erstellung einer Einschränkung:

  • veranlassen, dass ein gleichnamiger Index erstellt wird
  • Verweigern Sie das Löschen des erstellten Index, da eine Einschränkung ohne diesen nicht existieren darf

Wenn Sie gleichzeitig die Einschränkung löschen, wird der zugehörige Index gelöscht.

Gibt es also einen tatsächlichen Unterschied zwischen a PRIMARY KEYoder UNIQUE INDEX:

  • NULLWerte sind PRIMARY KEYim UNIQUEIndex nicht zulässig , aber im Index zulässig . und wie bei Mengenoperatoren (UNION, EXCEPT, INTERSECT), NULL = NULLwas bedeutet, dass Sie nur einen Wert haben können, da zwei NULLs als Duplikate voneinander gefunden werden;
  • PRIMARY KEYPro Tabelle darf nur einer vorhanden sein, während 999 eindeutige Indizes erstellt werden können
  • Wenn eine PRIMARY KEYEinschränkung erstellt wird, wird sie als Cluster erstellt, es sei denn, die Tabelle enthält bereits einen Clustered-Index oder NONCLUSTEREDwird in ihrer Definition verwendet. Wenn ein UNIQUEIndex erstellt wird, wird er so erstellt, als wäre NONCLUSTEREDer nicht spezifisch CLUSTEREDund existiert bereits nicht.

2

Wenn Sie es zu einem Primärschlüssel machen, sollte automatisch ein Index dafür erstellt werden.


1

In SQL Server wird der Primärschlüssel im Allgemeinen automatisch indiziert. Dies ist wahr, garantiert jedoch keine schnellere Abfrage. Der Primärschlüssel bietet eine hervorragende Leistung, wenn nur 1 Feld als Primärschlüssel vorhanden ist. Wenn jedoch mehrere Felder als Primärschlüssel vorhanden sind, basiert der Index auf diesen Feldern.

Beispiel: Feld A, B, C sind der Primärschlüssel. Wenn Sie also eine Abfrage basierend auf diesen drei Feldern in Ihrer WHERE-Klausel durchführen, ist die Leistung gut, ABER wenn Sie mit dem Feld Nur C in der WHERE-Klausel abfragen möchten wird keine gute Leistung bekommen. Um Ihre Leistung zum Laufen zu bringen, müssen Sie das C-Feld manuell indizieren.

Meistens wird das Problem erst angezeigt, wenn Sie mehr als 1 Million Datensätze erreicht haben.


0

Ich habe eine riesige Datenbank ohne (separaten) Index.

Jedes Mal, wenn ich nach dem Primärschlüssel abfrage, sind die Ergebnisse für alle intensiven Zwecke sofort verfügbar.


Das liegt daran, dass die PK ein Clustered-Index ist. Sehen Sie sich Ihren Abfrageplan an
SQLMenace

0

Primärschlüssel werden automatisch indiziert

Sie können mit dem pk je nach Verwendung zusätzliche Indizes erstellen

  • Index Postleitzahl, ID kann hilfreich sein, wenn Sie häufig nach Postleitzahl und ID auswählen
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.