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.
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:
WHERE column='ABC'
oder eine Join-Bedingung ON a.column = B.someothercolumn
. WHERE column BETWEEN 'ABC' AND 'DEF'
gibt es noch andere weniger offensichtliche Beispiele, wie zum Beispiel eine teilweise Übereinstimmung: WHERE column LIKE 'ABC%'
. 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.
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
Tags und Links sql-server