SQL-Server - lohnt es sich, große String-Schlüssel zu indizieren?

8

Ich habe eine Tabelle mit einem großen String-Schlüssel (varchar (1024)), den ich auf dem SQL-Server indizieren wollte (ich möchte in der Lage sein, schnell darüber zu suchen, aber auch Einfügungen sind wichtig). In Sql 2008 bekomme ich keine Warnung dafür, aber unter Sql Server 2005 sagt es mir, dass es 900 Bytes überschreitet und dass Einfügungen / Updates mit der Spalte über diese Größe fallengelassen werden (oder etwas in diesem Bereich)

Was sind meine Alternativen, wenn ich diese große Spalte indexieren möchte? Ich weiß nicht, ob es sich lohnt, wenn ich es könnte.

    
Ghita 03.11.2011, 21:11
quelle

2 Antworten

13

Ein Index mit allen Schlüsseln nahe 900 Bytes wäre sehr groß und sehr tief (sehr wenige Schlüssel pro Seite führen zu sehr großen B-Bäumen).

Es hängt davon ab, wie Sie die Werte abfragen möchten. Ein Index ist in mehreren Fällen nützlich:

  • wenn ein Wert geprüft wird. Dies ist die typischste Verwendung, wenn ein genauer Wert in der Tabelle gesucht wird. Typische Beispiele sind WHERE column='ABC' oder eine Join-Bedingung ON a.column = B.someothercolumn .
  • wenn ein Bereich gescannt wird. Dies ist auch ziemlich typisch, wenn ein Bereich von Werten in der Tabelle gesucht wird. Neben dem offensichtlichen Beispiel von WHERE column BETWEEN 'ABC' AND 'DEF' gibt es noch andere weniger offensichtliche Beispiele, wie zum Beispiel eine teilweise Übereinstimmung: WHERE column LIKE 'ABC%' .
  • eine Bestellanforderung. Diese Verwendung ist weniger bekannt, aber Indizes können einer Abfrage mit einer expliziten ORDER BY column -Anforderung helfen, eine Stop-and-Go-Sortierung zu vermeiden, und können auch bestimmte versteckte Sortieranforderungen unterstützen, wie zB ROW_NUMBER() OVER (ORDER BY column) .

Also, warum brauchen Sie den Index? Welche Art von Abfragen würden es verwenden?

Für Bereichs-Scans und Bestellanforderungen gibt es keine andere Lösung, als den Index zu haben, und Sie müssen die Kosten des Index gegenüber den Vorteilen abwägen.

Bei Probes können Sie möglicherweise Hash verwenden, um die Indizierung einer sehr großen Spalte zu vermeiden. Erstellen Sie eine persistente berechnete Spalte als column_checksum = CHECKSUM(column) und indexieren Sie dann für diese Spalte. Abfragen müssen neu geschrieben werden, um WHERE column_checksum = CHECKSUM('ABC') AND column='ABC' zu verwenden. Eine sorgfältige Abwägung wäre erforderlich, um den Vorteil eines engen Index (32-Bit-Prüfsumme) gegenüber den Nachteilen einer Kollisionsdoppelprüfung und dem Fehlen von Bereichsscan- und Bestellfähigkeiten abzuwägen.

nach dem Kommentar

Ich hatte einmal ein ähnliches Problem und habe eine Hash-Spalte verwendet. Der Wert war zu groß zum Indexieren (& gt; 1K) und ich musste auch den Wert in eine ID zum Speichern umwandeln (im Grunde ein Wörterbuch). Etwas in der Art:

%Vor%

In diesem Fall ist die Dictionary-Tabelle als gruppierter Index für die Spalte values_hash organisiert, die alle kollidierenden Hash-Werte zusammenfasst. Die id -Spalte wird hinzugefügt, um den Clustered-Index eindeutig zu machen, sodass kein versteckte Unifier-Spalte . Diese Struktur macht die Suche nach @value so effizient wie möglich, ohne einen sehr ineffizienten Index für value und umgeht die Begrenzung um 900 Zeichen. Der Primärschlüssel in id ist nicht geclustert, was bedeutet, dass das Nachschlagen von value von und id den Overhead einer zusätzlichen Probe im Clustered-Index verursacht.

Nicht sicher, ob dies Ihr Problem löst, Sie wissen offensichtlich mehr über Ihre tatsächlichen Szenarien als ich. Außerdem behandelt der Code keine Fehlerbedingungen und kann tatsächlich doppelte @ value-Einträge einfügen, die korrekt sind oder nicht.

    
Remus Rusanu 03.11.2011, 21:51
quelle
1

Allgemeine Index-Design-Richtlinien

  

Wenn Sie einen Index entwerfen, beachten Sie die folgenden Spaltenrichtlinien:

     
  • Halten Sie die Länge des Indexschlüssels für Clustered-Indizes kurz. Darüber hinaus profitieren Clustered-Indizes davon, dass sie auf unique erstellt wurden   oder Nichtnull-Spalten. Weitere Informationen finden Sie unter Clustered-Index-Design   Richtlinien.

  •   
  • Spalten mit den Datentypen ntext, text, image, varchar (max), nvarchar (max) und varbinary (max) können nicht als angegeben werden   Indexschlüsselspalten. Varchar (max), nvarchar (max),   varbinary (max) und xml Datentypen können an einem Nonclustered teilnehmen   Index als Nicht-Schlüssel-Indexspalten. Weitere Informationen finden Sie unter Index mit   Eingeschlossene Spalten.

  •   
  • Untersuchen Sie die Datenverteilung in der Spalte. Häufig wird eine lang andauernde Abfrage durch Indexieren einer Spalte mit wenigen eindeutigen Werten oder durch   einen Join auf einer solchen Spalte durchführen. Dies ist ein grundlegendes Problem mit   die Daten und Abfrage, und in der Regel kann nicht ohne gelöst werden   Identifizieren dieser Situation. Zum Beispiel ein physisches Telefon   Das alphabetisch nach Nachnamen sortierte Verzeichnis wird nicht beschleunigt   eine Person suchen, wenn alle Leute in der Stadt Smith oder Jones genannt werden

  •   
    
sll 03.11.2011 21:23
quelle

Tags und Links