Verlangsamt das Hinzufügen eines Index für die Bitspalte die Einfügungen erheblich?

11

Ich habe einen Tisch mit ungefähr 1 Million bis 5 Millionen Datensätzen. Bei einem kleinen Teil dieser Datensätze ist eine Bitspalte auf 'TRUE' gesetzt. Müssen schnell diese Aufzeichnungen finden. Ich denke, dass der Index die Suche in dieser Spalte beschleunigen kann, aber ich habe Angst vor INSERTs. Daher meine Frage.

Die Datenbank funktioniert wie eine Art Data Warehouse, daher gibt es viele SELECTs und kleine (bis zu 10-20 pro Tag), aber ziemlich große INSERTs (bis zu 200.000 Datensätze gleichzeitig). Ich habe Angst vor einer längeren Importzeit in die Datenbank.

Marioosh
quelle
5
Welche Version von SQL Server? Wenn 2008+ wie ein gefilterter Index klingt, könnte dies das sein, was Sie brauchen.
Martin Smith
SQL Server 2005
Marioosh
1
Sie können die Tabelle aufteilen (fügen Sie eine neue Tabelle mit nur einer Spalte hinzu, der PK der Tabelle, die nur mit den Zeilen gefüllt wird, für die die Bitspalte wahr ist - am Ende können Sie sogar die Bitspalte entfernen.) Eine indizierte Tabelle Ansicht würde auch 2005 mit dem Fehlen von Teilindizes funktionieren.
Ypercubeᵀᴹ
Seien Sie vorsichtig mit der indizierten Ansicht. Wie Sie bereits erwähnt haben, haben Sie 10 bis 20 große Einfügungen pro Tag. Die Wartung der indizierten Ansicht kann den Vorteil eines Leistungsgewinns übertreffen. Ich glaube nicht, dass Sie eine "Out-of-the-Box" -Funktion von SQL 2005 verwenden können, um Ihre Situation zu verbessern. Wenn Sie jedoch die aktuelle Tabellenstruktur und den vorhandenen Index auflisten, finden wir möglicherweise ein alternatives Design.
Anup Shah

Antworten:

8

Ein Index für ein Bit für 1 Million Datensätze ist nutzlos. Der Optimierer wird es niemals verwenden, Sie zahlen nur für die Wartung. Eine viel bessere Alternative besteht darin, dieses Bit als Schlüssel ganz links im Clustered-Index hinzuzufügen.

Aber ich werde im Dunkeln einen Blindschuss machen und vermuten, dass es sich um ein Warteschlangenmuster handelt: Datensätze werden in der Tabelle abgelegt, wobei das Bit auf 'TRUE' (dh 'needsprocessing = true') gesetzt ist, und dann wird ein Hintergrundprozess angezeigt Führt für diese Datensätze eine Verarbeitung durch und aktualisiert das Bit auf FALSE. Dies ist ein allgegenwärtiges Muster, das auch liebevoll als "Rezeptmuster für Leistungskatastrophen" bezeichnet wird. Ich würde empfehlen, die Datensätze in die Tabelle einzufügen und gleichzeitig eine Benachrichtigung (könnte so einfach wie die neu eingefügte Datensatz-ID sein) in eine Warteschlange zu stellen . Siehe Verwenden von Tabellen als Warteschlangen .

Remus Rusanu
quelle
1
Ich sehe keinen guten Grund darin, die Bitspalte ganz links zu platzieren, da wir andere Filterspalten mit hoher Kardinalität nicht kennen. Bisher habe ich gesehen, dass die BIT-Spalte die letzte Wahl im Clustered-Index ist. aber ja, +1 für die nette Referenz von "Verwenden von Tabellen als Warteschlangen".
Anup Shah
2
Eigentlich habe ich einen Test durchgeführt und ja, es wird der Index verwendet. Erstellen Sie eine Tabelle (ID-Identität, myBit-Bit). Fügen Sie 100 Zeilen hinzu, wobei das Bit 0 und 2000000 ist, wobei das Bit 1 ist. Stellen Sie sicher, dass die Statistiken aktualisiert sind (falls erforderlich), und führen Sie eine Abfrage für myBit = 0 aus, und der Index wird verwendet.
Kenneth Fisher
@KennethFisher, außer dass in dem typischen Hochgeschwindigkeitsmuster von TRUE / Update auf FALSE sofort die Statistiken immer veraltet sind. Wenn Sie lieber russisches Roulette mit dem Optimierer spielen als ein klares Design zu
erstellen
" Ich werde es niemals verwenden" Diese Aussage gilt für 99% der Fälle, aber wir wissen nicht, in welchem ​​Fall sich das OP befindet. Ich habe erfolgreich auf Bit indiziert. Anwendungsfälle existieren.
usr
Frage - ist die Antwort hier falsch, insbesondere> "Wenn Sie ein Bitfeld (oder einen engen Bereich) indizieren, reduzieren Sie den Arbeitssatz nur um die Anzahl der Zeilen, die diesem Wert entsprechen. Wenn Sie eine kleine Anzahl von Zeilen haben, die diesem Wert entsprechen." Dies würde Ihren Arbeitssatz erheblich reduzieren . Bei einer großen Anzahl von Zeilen mit einer 50/50-Verteilung können Sie möglicherweise nur einen sehr geringen Leistungsgewinn erzielen, anstatt den Index auf dem neuesten Stand zu halten. " In welchem ​​Fall würde ein Index für ein Bit, das mit 1% der Datensätze übereinstimmt, die Notwendigkeit beseitigen, 99% von 1 Million nach einem signifikanten Anstieg zu durchsuchen?
Drzaus
2

Wie @MartinSmith sagte, wäre ein gefilterter Index die perfekte Lösung, wenn Sie jemals ein Upgrade auf SQL 2008 durchführen würden. In der Zwischenzeit erhöht jedoch im Allgemeinen JEDER hinzugefügte Index Ihre Ladezeit. Kleine Indizes weniger als große.

Eine Sache, die ich mir ansehen würde, ist, wenn Sie einen vorhandenen Index haben, der geändert werden kann. Angenommen, Ihre vorhandenen Abfragen verwenden einen bestimmten Index, dann sollte das Hinzufügen der Bitspalte am Ende dieses Index nur minimale Auswirkungen auf Einfügungen und den positiven Effekt haben, den Sie auf Ihre Abfragen haben.

Als nächstes sollten Sie sich ansehen: "Habe ich bereits viele Indizes?" Es gibt keine feste Regel, was "viel" ist, aber ich halte mich normalerweise an eine Regel von 10 Indizes, es sei denn, ich brauche WIRKLICH eine neue.

Letzter Gedanke, testen Sie es auf einer Testinstanz. Richten Sie eine Tabelle mit einigen Millionen Zeilen ein, führen Sie Ihre Last darauf aus, fügen Sie Ihren Index hinzu, führen Sie dann Ihre Last erneut aus und prüfen Sie, ob Sie eine signifikante Verlängerung der Ladezeit feststellen.

Nur Sie können wirklich entscheiden, was "bedeutend" ist. Ich habe Maschinen, bei denen das Hinzufügen von 5 Minuten zur Ladezeit "signifikant" ist, und andere, bei denen ich sicher ein paar Stunden mehr sehen konnte.

BEARBEITEN:

Eine andere Möglichkeit besteht darin, Ihre Tabelle zu partitionieren. Möglicherweise müssen Sie eine partitionierte Ansicht verwenden, wenn Sie die Enterprise Edition nicht verwenden. Dies sollte jedoch hilfreich sein. Sie setzen Ihre Bit 0s in eine Partition und Ihre Bit 1s in eine andere. Angenommen, Sie fügen nur die eine oder andere Version ein, dann können Sie Ihre Einfügungen sogar beschleunigen.

Kenneth Fisher
quelle