3 Stimmen

Optimierung von SQL Server-Indizes

Ich habe eine Tabelle mit mehreren nicht PK-bezogenen Indizes. Leider gibt es eine gewisse Duplizität, da mehrere Indizes auf die gleiche Spalte mit der gleichen Sortierreihenfolge verweisen. Ich erstelle in der Regel abdeckende Indizes, die Aggregationen von nicht PK-bezogenen Indizes für meine Tabellen darstellen, denn solange die Spalte indiziert ist, wird sie gegebenenfalls bei Abfragen verwendet. Meine Frage ist einfach: Vergeudet die Indizierung derselben Spalte in mehreren Indizes in derselben Sortierreihenfolge Ressourcen, oder weiß SQL Server, dass eine Spalte bereits indiziert ist und verweist nur zu Optimierungszwecken auf sie?

UPDATE: Ein zukünftiger Punkt wäre zu fragen, ob doppelte Indizes mit leichten Abweichungen die ORDER BY-Aktivitäten verbessern. Wenn ich z. B. nach A, B DESC, D ordne, würde ein spezieller Index mit dieser Reihenfolge tatsächlich die Leistung gegenüber einem einzelnen abdeckenden Index erhöhen, der diese Spalten mit der gleichen Sortierreihenfolge enthält. Ich hatte den Eindruck, dass ORDER BY sich nur auf Indizes stützt und aus Leistungsgründen keine speziellen Indizes benötigt.

5voto

marc_s Punkte 701497

Jeder Index wird separat geführt - es gibt keine Querverweise und so weiter. Wenn es sich bei diesen Indizes also um Duplikate handelt, kann es sein, dass Sie etwas Zeit verschwenden. Aber: Es kann durchaus Sinn machen, eine einzelne Spalte in mehrere Indizes aufzunehmen - Dinge wie zusammengesetzte Indizes (mehrere Felder) usw. können sinnvoll sein, wenn sie nebeneinander vorhanden sind.

SQL Server hat seit 2005 eine wirklich nette Funktion namens DMV (Dynamic Management View), die es Ihnen ermöglicht, nach

  • Indizes, die überhaupt nicht verwendet werden
  • fehlende Indizes, die das Laden Ihrer Abfrage beschleunigen könnten

Fehlende Indizes finden:

SELECT  
    object_name(object_id), d.*, s.*
FROM
    sys.dm_db_missing_index_details d 
INNER JOIN 
    sys.dm_db_missing_index_groups g ON d.index_handle = g.index_handle
INNER JOIN 
    sys.dm_db_missing_index_group_stats s ON    g.index_group_handle = s.group_handle
WHERE   
    database_id = db_id()
ORDER BY  
    object_id

Ungenutzte Indizes finden:

DECLARE  @dbid INT

SELECT @dbid = DB_ID(DB_NAME())

SELECT   
    OBJECTNAME = OBJECT_NAME(I.OBJECT_ID),
    INDEXNAME = I.NAME,
    I.INDEX_ID
FROM     
    SYS.INDEXES I
JOIN 
    SYS.OBJECTS O ON I.OBJECT_ID = O.OBJECT_ID
WHERE    
    OBJECTPROPERTY(O.OBJECT_ID, 'IsUserTable') = 1
    AND I.INDEX_ID NOT IN (SELECT S.INDEX_ID
                            FROM SYS.DM_DB_INDEX_USAGE_STATS S
                            WHERE S.OBJECT_ID = I.OBJECT_ID
                                    AND I.INDEX_ID = S.INDEX_ID
                                    AND DATABASE_ID = @dbid)
ORDER BY 
    OBJECTNAME, I.INDEX_ID, INDEXNAME ASC

2voto

David Hogue Punkte 1761

Dadurch wird der Speicherplatz doppelt belegt, vor allem aber werden Einfügungen verlangsamt, während alle Indizes aktualisiert werden.

1voto

Ray Punkte 21047

Jedes Mal, wenn eine Spalte in einen Index aufgenommen wird, wird Platz verbraucht - auch wenn Sie andere ähnliche Indizes haben.

1voto

Joel Coehoorn Punkte 377088

Mir ist nicht klar, worauf Sie hinauswollen.

Betrachten Sie einen Index für eine Tabelle mit den Spalten A, B, C und D. Sie haben einen Index für (A, B) und (B, A), alle aufsteigend sortiert. In diesem Fall werden zwar zwei Indizes erstellt, aber der zusätzliche Index ist nicht überflüssig, denn die zusätzlichen Spalten in einem Index helfen nur dann bei der Suche, wenn es doppelte Zeilen für alle vorangehenden Spalten im Index gibt.

Andererseits ein Index auf (A,B) mit der zusätzlichen "abdeckenden" Spalte C und ein weiterer Index (A,B) mit der zusätzlichen "abdeckenden" Spalte D wird Platzverschwendung. Sie sollten einfach (A,B) + C,D verwenden.

1voto

burnall Punkte 822

Die Anzahl der zu verwendenden Indizes ist eine Entscheidung zwischen Performance Selects und Insert/Update/Delete. Der Speicherplatz ist weniger wichtig.

Ich habe viele Male Indizes für die Tabelle t(A, B, C) wie 'A', 'A,B', 'A,B,C'. Natürlich ist das nicht nützlich. Einige Tools generieren gerne solche Indizes. Es ist auch keine gute Idee, Schlüssel für ALLE möglichen Abfragen zu erstellen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X