Wie wirken sich große INCLUDE-Indexfelder auf die Systemleistung aus?

15

Diese Frage bezieht sich auf die SQL Server-Indexleistung mit einem varchar(2000) als INCLUDEin 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 aufzunehmen INCLUDE?

  • INCLUDEHaben 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".

RaoulRubin
quelle
Wie lang sind die tatsächlichen Werte? Ein, VARCHAR(2000)der normalerweise nur zehn Zeichen speichert, ist eine Sache; Feste 2.000 Bytes pro Datensatz sind etwas anderes.
Jon of All Trades
Nur eine Beobachtung: Etwas, das hier "riecht", ist, dass die große Spalte entweder 1) freien Text enthalten kann, in welchem ​​Fall Abfragen von Umschreibungen zur Verwendung eines FULLTEXT-Indexes profitieren können, oder 2) "von Menschen lesbare" codierte Daten (z. B. breite intelligente Daten) Schlüssel wie eine VIN), die von der Aufteilung in separate Spalten oder von beibehaltenen berechneten Spalten mit INDEXen profitieren könnten. Mit anderen Worten, der Informationsfluss und die Datenänderungen sind nicht gut geplant.
Graeme
1
Ja #Graeme, hier riecht es schlecht - ich denke, es heißt "Legacy". Es gibt eine Vielzahl von Problemen in diesen Datenbanken.
RaoulRubin

Antworten:

14

Ü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.

Grant Fritchey
quelle
Vielen Dank, Grant. Wie ich bereits erwähnt habe, sind gute Leistungsdaten rar, daher die abstrakte Frage. Ich habe keine Erfahrung mit der Überwachung der Leistungskosten für die Seitengröße. Meine Vermutung ist, dass es ein Problem ist, ob ich ein paar Statistiken bekommen kann.
RaoulRubin
1
Wenn Sie die Statistik-E / A für die Abfrage aktivieren, erfahren Sie viel, logische Lesevorgänge geben die Anzahl der Seiten an, auf die zugegriffen wurde. Sie können auch die Sek./Lesevorgänge von Perfmon-Zählern überwachen, um allgemeine Leistungsinformationen zu erhalten.
Grant Fritchey
6

Können Sie den aktuellen gruppierten Indexschlüssel überprüfen und möglicherweise col2stattdessen 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 vielen ifund butist 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.

Remus Rusanu
quelle
Ihr Vorschlag zur PK ist eine großartige Idee, obwohl ich ihn in diesem Fall nicht anwenden kann - eine vorhandene PK ist für andere Abfragen erforderlich. (Dies ist eine Technik, die ich in der Toolbox behalten werde!)
RaoulRubin
4

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.

Aaron Bertrand
quelle
Insgesamt ist read vs update meist ausgeglichen. Organisations- und Datenschutzprobleme erschweren es, nützliche Statistiken und realistische Tests zu erhalten. Da wir meistens blind fliegen, müssen wir die Dinge von einem abstrakten Standpunkt aus betrachten (daher diese Frage). Testen bedeutet, Produktionsänderungen voranzutreiben und Ergebnisse zu beobachten - sehr riskant.
RaoulRubin
2
Ziehen die meisten Lesevorgänge diese 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).
Aaron Bertrand
3

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).

AK
quelle