Diese Frage bezieht sich auf die SQL Server-Indexleistung mit einem varchar(2000)
als INCLUDE
in einem abdeckenden Index.
Ich versuche, die Leistung in einer langsamen und instabilen Datenbankanwendung zu verbessern. In einigen Fällen werden die Daten durch großen varchar Strings zugegriffen wird , mit den Abfragen einschließlich multple String - Operationen wie SUBSTRING()
, SPACE()
und DATALENGTH()
. Hier ist ein vereinfachtes Beispiel für den Zugriff.
update fattable set col3 =
SUBSTRING(col3,1,10) + '*' +
SUBSTRING(col3,12,DATALENGTH(col3)-12)
from fattable where substring(col3,10,1) = 'A' and col2 = 2
Das Schema sieht folgendermaßen aus:
CREATE TABLE [dbo].[FatTable](
[id] [bigint] IDENTITY(1,1) NOT NULL,
[col1] [nchar](12) NOT NULL,
[col2] [int] NOT NULL,
[col3] [varchar](2000) NOT NULL, ...
Der folgende Index wurde mit einem überdeckenden Feld in der großen Textspalte definiert.
CREATE NONCLUSTERED INDEX [IndexCol2Col3] ON [dbo].[FatTable] ( [col2] ASC )
INCLUDE( [col3] )
Nach dem, was ich gelesen habe, ist es SCHLECHT, große Datenfelder in einen Index aufzunehmen. Ich habe mehrere Artikel gelesen, darunter http://msdn.microsoft.com/en-us/library/ms190806.aspx denen die Auswirkungen von Paging und Festplattengröße auf die Indexleistung erläutert werden. Vor diesem Hintergrund verwendet der Abfrageplan definitiv den Deckungsindex. Ich habe nicht genügend Informationen, um zu bestimmen, wie viel mich das in Bezug auf die Systemlast tatsächlich kostet. Ich weiß, dass das System insgesamt schlecht funktioniert, und ich bin besorgt, dass dies eines der Probleme ist. Fragen:
Ist es jemals eine gute Idee , diese
varchar(2000)
Spalte in den Index aufzunehmenINCLUDE
?INCLUDE
Haben die Felder, da sie in Blattknoten gespeichert sind, große Auswirkungen auf die Indexleistung?
Update: Danke für die tollen Antworten! Dies ist in gewisser Hinsicht eine unfaire Frage - wie Sie sagen, gibt es keine absolut richtige Antwort ohne tatsächliche Statistiken und Profilerstellung. Wie so viele Leistungsprobleme lautet die Antwort vermutlich "es kommt darauf an".
quelle
VARCHAR(2000)
der normalerweise nur zehn Zeichen speichert, ist eine Sache; Feste 2.000 Bytes pro Datensatz sind etwas anderes.Antworten:
Überhaupt ist es ein großes Wort, aber im Allgemeinen würde ich kein varchar (2000) -Feld in ein INCLUDE setzen.
Und ja, die Art und Weise, wie Daten auf Seitenebene gespeichert werden, kann die Leistung des Index stark beeinträchtigen, je nachdem, wie der Index verwendet wird.
Die Sache ist, je mehr Datenzeilen Sie in eine Seite packen können, desto weniger Seiten müssen abgerufen werden, desto schneller ist Ihr System zum größten Teil. Das Hinzufügen einer sehr großen Spalte bedeutet, dass weniger Informationen auf einer Seite gespeichert sind. Bei Bereichsabfragen oder Scans müssen daher mehr Seiten gelesen werden, um die Daten abzurufen.
Um sicherzugehen, dass dies ein Problem in Ihrer Abfrage oder auf Ihrem System ist, müssen Sie die Lesevorgänge überwachen, insbesondere die Anzahl der von der Abfrage verwendeten Seiten.
quelle
Können Sie den aktuellen gruppierten Indexschlüssel überprüfen und möglicherweise
col2
stattdessen den gruppierten Indexschlüssel erstellen? Auf diese Weise erhalten Sie das Deckungsverhalten "Einschließen" (da Clustered-Indizes immer "Alles einschließen"), ohne die Daten zu duplizieren. Dies unterliegt natürlich vielenif
undbut
ist vielleicht dennoch eine Überlegung wert. Wenn der aktuelle gruppierte Index eine Einschränkung (Primärschlüssel, eindeutig) erzwingt, müsste diese Einschränkung natürlich in einen nicht gruppierten Index verschoben werden.quelle
Es ist schwer zu beantworten. Es hängt alles von Ihrem Lese- / Schreibverhältnis ab. Haben Sie eine Workload getestet oder einen gesamten Geschäftszyklus auf einem Testsystem mit und ohne die enthaltene Spalte simuliert? Das Nachschlagen ohne kostet zwar viel, aber wenn Sie die Daten häufiger aktualisieren, als Sie sie lesen, ist dies möglicherweise in Ordnung.
quelle
VARCHAR(2000)
Spalte tatsächlich ab oder beheben Sie die Leistung einer sehr spezifischen Abfrage, die die meisten Abfragen nicht darstellt? Wie Grant vorschlägt , ist es wahrscheinlich besser, den Preis für das Nachschlagen zu zahlen, wenn Sie ihn benötigen, aber nicht für den Speicher zu zahlen, wenn Sie ihn nicht benötigen, wenn diese Spalte nicht in vielen Abfragen verwendet wird oder Probleme bei Suchvorgängen verursacht . Auch hier ist es sehr schwer zu sagen, auf welcher Seite des Zauns Sie sich befinden sollten, da wir keine genauen Angaben haben (und noch schwieriger, weil Sie nicht testen können - Sie sollten danach streben, das zu beheben).Ich weiß, dass ich für diese Party zu spät komme, aber ich würde genau die Ausdrücke indizieren, die zum Auffinden von Zeilen verwendet werden, z. B. Teilzeichenfolge (Spalte 3, 10, 1). Wenn die gesamte Spalte 3 jemals verwendet wird, würde ich CHECKSUM (Spalte 3) indizieren (wobei ich verstehe, dass es natürlich zu Kollisionen kommen kann).
quelle