Sollte ich viele einzelne Feldindizes anstelle von bestimmten mehrspaltigen Indizes verwenden?


35

In dieser Frage geht es um die Effektivität einer SQL Server-Indizierungstechnik. Ich denke, es ist als "Indexschnittstelle" bekannt.

Ich arbeite mit einer vorhandenen SQL Server (2008) -Anwendung, die eine Reihe von Leistungs- und Stabilitätsproblemen aufweist. Die Entwickler haben einige seltsame Dinge mit Indizierung gemacht. Ich habe zu diesen Themen keine schlüssigen Benchmarks erhalten und auch keine wirklich gute Dokumentation im Internet gefunden.

Es gibt viele durchsuchbare Spalten in einer Tabelle. Die Entwickler erstellten einen einzelnen Spaltenindex für JEDE der durchsuchbaren Spalten. Die Theorie war, dass SQL Server in der Lage sein würde, jeden dieser Indizes zu kombinieren (zu schneiden), um unter den meisten Umständen effizient auf die Tabelle zuzugreifen . Hier ist ein vereinfachtes Beispiel (echte Tabelle hat mehr Felder):

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

CREATE NONCLUSTERED INDEX [IndexCol1] ON [dbo].[FatTable]  ( [col1] ASC )
CREATE NONCLUSTERED INDEX [IndexCol2] ON [dbo].[FatTable] ( [col2] ASC )

select * from fattable where col1 = '2004IN' 
select * from fattable where col1 = '2004IN' and col2 = 4

Ich denke, dass mehrere Spaltenindizes, die auf Suchkriterien abzielen, viel besser sind, aber ich kann mich irren. Ich habe Abfragepläne gesehen, die zeigen, dass SQL Server bei zwei Indexsuchen eine Hash-Übereinstimmung ausführt. Vielleicht ist das sinnvoll, wenn Sie nicht wissen, wie die Tabelle durchsucht wird? Vielen Dank.


@brentozar hat ein schönes Video über Indizes, das es wert ist gesehen zu werden: brentozar.com/sql-server-training-videos/…
DForck42

Antworten:


38

Was Sie brauchen, sind Indizes abdecken , dh. Indizes, die eine Abfrage alleine erfüllen können. Ein 'abdeckender' Index hat jedoch ein Problem: Er deckt eine bestimmte Abfrage ab . Um eine gute Indizierungsstrategie zu entwickeln, müssen Sie Ihre Arbeitslast verstehen: Welche Abfragen treffen auf die Datenbank, welche sind kritisch und welche nicht, wie oft wird jeder Abfragetyp usw. usw. ausgeführt. Und dann Sie Vergleichen Sie dies mit den Schreib- und Aktualisierungskosten für jeden Index. Dort haben Sie Ihre Indexierungsstrategie. Wenn es kompliziert klingt , das ist , weil es ist kompliziert.

Sie können jedoch einige Faustregeln anwenden. Der MSDN deckt die Grundlagen recht gut ab:

Es gibt auch eine Vielzahl von Artikeln, die von der Community beigesteuert wurden, z. Aufzeichnung von Webcasts - DBA Darwin Awards: Index Edition .

Und um Ihre Frage speziell zu beantworten: Es können separate Indizes für jede Spalte verwendet werden , vorausgesetzt, jede Spalte weist eine hohe Selektivität auf (viele unterschiedliche Werte, wobei jeder Wert nur einige Male in der Datenbank vorkommt). Der resultierende Zugriffsplan, der eine Hash-Verknüpfung zwischen zwei Indexbereichsscans verwendet, funktioniert normalerweise recht gut. Spalten mit geringer Selektivität (wenige unterschiedliche Werte, wobei jeder Wert mehrfach in der Datenbank vorkommt) sind für sich genommen nicht indizierbar. Der Abfrageoptimierer ignoriert sie einfach. Viele geringe Selektivität Spalten mal machen gute Allerdings Verbund Tasten , wenn sie mit einer hohen Selektivität Spalte gekoppelt sind.


Danke Remus. Ich frage mich, welchen relativen Vorteil das Erstellen gezielter mehrspaltiger Indizes (und Includes) gegenüber der Verwendung separater Indizes hat. Wenn es "ganz gut funktioniert" ist gut genug, kann es in Ordnung sein. (Wirft die Indizes für Felder mit geringer Selektivität aus). Diese Technik sollte helfen, wenn wir keinen Zugriff auf die Produktionsdatenbank haben und unsere Indizes nicht auf die tatsächliche Verwendung ausrichten können.
RaoulRubin
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.