it-swarm.com.de

Was ist der Zweck von PAD_INDEX in dieser SQL Server-Einschränkung?

Ich habe die folgende Einschränkung, die auf eine meiner Tabellen angewendet wird, aber ich weiß nicht, was PAD_INDEX bedeutet.

Kann mich jemand aufklären?

CONSTRAINT [PK_Employees] PRIMARY KEY CLUSTERED 
(
    [EmployeeId] ASC
) WITH (PAD_INDEX  = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
        ^--------------^
         this part here
37
radio star

Ein Index in SQL Server ist ein B-Tree

  • FILLFACTOR gilt für die unterste Ebene
    Dies ist der Blattknoten/Datenschicht in der Abbildung unten

  • PAD_INDEX ON bedeutet "FILLFACTOR auf alle Layer anwenden"
    Dies sind die Zwischenstufen im Bild (zwischen Stamm und Daten).

Das bedeutet, dass PAD_INDEX nur nützlich ist, wenn FILLFACTOR gesetzt ist. FILLFACTOR bestimmt, wie viel Speicherplatz auf einer Datenseite ungefähr vorhanden ist. 

Ein Bild von MSDN :

B-Tree structure

55
gbn

Grundsätzlich setzen Sie PAD_INDEX = ON, wenn Sie regelmäßig zahlreiche zufällige Änderungen des Index erwarten. 

Dies hilft, Indexsplits zu vermeiden.

Ich habe es aktiviert, wenn ich erwarte, dass mehr als 30% der im Index enthaltenen Zufallsdatensätze regelmäßig gelöscht werden. 

47
SQLador

Von MSDN :

PAD_INDEX = {ON | AUS }

Gibt die Auffüllung des Index an. Die Standardeinstellung ist AUS.

ON: Der durch fillfactor angegebene Prozentsatz an freiem Speicherplatz wird auf die Indexseiten der Zwischenebene angewendet.

OFF oder fillfactor ist nicht angegeben: Die Seiten der mittleren Ebene werden fast bis zur vollen Kapazität gefüllt, so dass ausreichend Platz für mindestens eine Zeile der maximalen Größe bleibt, die der Index haben kann.

Die Option PAD_INDEX ist nur nützlich, wenn FILLFACTOR angegeben ist, da PAD_INDEX den von FILLFACTOR angegebenen Prozentsatz verwendet. Wenn der für FILLFACTOR angegebene Prozentsatz nicht groß genug ist, um eine Zeile zuzulassen, überschreibt Database Engine (Datenbankmodul) intern den Prozentsatz, um das Minimum zu berücksichtigen. Die Anzahl der Zeilen auf einer Zwischenindexseite ist niemals kleiner als zwei, unabhängig davon, wie niedrig der Füllfaktor ist.

In abwärtskompatibler Syntax entspricht WITH PAD_INDEX WITH PAD_INDEX = ON.

20
Edwin de Koning

Dies ist eigentlich ein sehr komplexes Thema. Das Einschalten von PAD_INDEX kann dramatische Auswirkungen haben auf die Leseleistung und den Speicherdruck in großen Tabellen. Je größer der Tisch, desto größer der Effekt. In der Regel würde ich sagen, dass Sie es auslassen möchten, es sei denn, Sie fallen in einige NICHT UNGEWÖHNLICHE Kategorien. Dann befolge diesen Rat sorgfältig. Wie im folgenden Beispiel gezeigt, kann das Anpassen von FILLFACTOR bei eingeschaltetem PAD_INDEX einen exponentiellen Effekt haben, der sorgfältig abgewogen werden muss.

  1. PAD_INDEX wirkt sich IMMER nachteilig auf das Lesen aus! Je niedriger Ihr FILLFACTOR ist, desto größer ist der Effekt, sodass Sie beim Einschalten genau auf den Wert von FILLFACTOR achten müssen. Bei großen Tabellen müssen Sie im Wesentlichen denken Sie nicht mehr über FILLFACTOR nach, um Blattsplits zu reduzieren, sondern über die Auswirkungen auf Zwischenaufblähungen im Vergleich zu Zwischensplits.
  2. PAD_INDEX hat selten eine nützliche Auswirkung auf Indizes mit weniger als 100.000 Zeilen und NIE eine positive Auswirkung auf Indizes, die Spalten vom Typ Identität oder Einfügezeit abdecken, bei denen sich Einfügungen immer am Ende der Tabelle befinden.
  3. Wenn Sie PAD_INDEX aktivieren, müssen Sie die negativen Effekte sorgfältig mit den positiven abwägen.

Faustregeln: PAD_INDEX ist bei nicht gruppierten Indizes selten nützlich, es sei denn, sie sind ziemlich breit, bei gruppierten Indizes sehr enger Tabellen oder bei Tabellen mit weniger als 100 KB Zeilen, sofern die Einfügungen nicht stark gruppiert und gerade sind dann kann es fraglich sein.

Sie MÜSSEN verstehen, wie es funktioniert: Wenn Sie in einen Index einfügen, muss die Zeile in den Blattblock passen, der den entsprechenden Bereich von Schlüsseln enthält. Clustered-Indizes haben in der Regel viel breitere Zeilen als Nicht-Clustered-Indizes, sodass ihre Blattblöcke weniger Zeilen enthalten. FillFactor schafft Platz für neue Zeilen im Blatt, aber bei sehr breiten Zeilen oder einer großen Anzahl von Einfügungen, die nicht gleichmäßig verteilt sind, ist es oft unpraktisch oder unmöglich, genügend Spielraum (1-Prozent-Füllung) zu schaffen, um Spalten zu verhindern.

Bei einer Teilung wird eine neue Zwischenzeile erstellt, die auf den neuen Block verweist, und diese Zeile muss in den entsprechenden Block passen. Wenn dieser Zwischenblock voll ist, muss er zuerst geteilt werden. Splits können bis zur Wurzel reichen, wenn Sie besonders Pech haben. Wenn sich die Wurzel aufteilt, wird eine neue Indexebene erstellt.

Der Punkt von PAD_INDEX besteht darin, einen Mindestbetrag an freiem Speicherplatz in Ihren Zwischenebenenblöcken zu erzwingen.

Nach einem Umbau ist in den unteren Ebenen möglicherweise nur wenig oder gar kein Platz mehr vorhanden. Wenn Sie viele Blattsplits haben und PAD_INDEX nicht aktiviert ist, können Sie Ihre Zwischenprodukte überall massiv aufteilen!

Meistens können Splits mit FILLFACTOR verwaltet werden. Die größeren Split-Probleme treten bei Einfügemustern auf, die praktisch garantieren, dass Sie nicht genug freien Speicherplatz haben. Wenn Sie PAD_INDEX aktivieren, wird dies durch die Bereitstellung von Speicherplatz auf tieferen Ebenen verringert. Wenn also ein Split auftritt, ist die Wahrscheinlichkeit geringer, dass viele mehrstufige Splits auftreten.

Beispielfall

Ich habe eine Kundentabelle mit 100.000 Zeilen. An einem bestimmten Tag sind ungefähr 5% meiner Kunden aktiv. Ich habe eine Tabelle, die die Aktivität des Kunden nach Zeit aufzeichnet. Im Durchschnitt führt ein Kunde 20 Aktionen aus und die Beschreibung benötigt im Durchschnitt 1 KB. Ich sammle also 100 MB Daten und gehe davon aus, dass ich bereits ein Jahr in der Tabelle habe - also 36 GB.

Die Tabelle enthält Einfügungen von 1-KB-Zeilen mit customer_number und insert_time (in dieser Reihenfolge) für Schlüsselspalten. Es ist klar, dass ein durchschnittlicher Kunde einen 8-KByte-Blattblock mehrmals aufteilt, während er die erwarteten 20 Zeilen einfügt, da jede Zeile unmittelbar nach der vorhergehenden Zeile in denselben Block eingefügt wird, bis sie sich aufteilt und aufteilt (man betrachtet einen Heap mit nur nicht gruppierten Daten) Indizes ...). Wenn der Zwischenblock, der auf das entsprechende Blatt zeigt, nicht genug Platz für mindestens 4 Zeilen hat (in Wirklichkeit wahrscheinlich 8, aber ...), muss das Zwischenelement aufgeteilt werden. Wenn der Schlüssel dieses Beispiels 22 Byte belegt, kann ein Zwischenblock 367 Einträge enthalten. Das bedeutet, dass ich 6% freien Speicherplatz in meinem Zwischenblock oder 94% Platz für die 4 Einträge benötige.

Beachten Sie, dass selbst ein 1% -FÜLLFAKTOR die Blattblockteilung nicht stoppt, da ein Block nur 8 Zeilen aufnehmen kann. Wenn Sie FILLFACTOR auf 80% setzen, kann nur eine Zeile vor dem Aufteilen des Blatts hinzugefügt werden. Wenn PAD_INDEX aktiviert ist, werden jedoch mehr als 800 Byte freier Speicherplatz pro Zwischenblock eingefügt. Das sind ~ 800 leere Bytes für JEDEN Zwischenblock, wenn ich nur 88 benötige.

Das ist wirklich wichtig!: Wenn ich also bereits 36 Millionen Zeilen in der Tabelle habe, bedeutet 80% 294 Zeilen pro Zwischenblock, was 122.000 Blöcke bedeutet, was bedeutet, dass ich 98 MB in meine Zwischenblockstruktur injiziert habe, wenn 94% lassen 345 Zeilen pro Block passen, so dass es nur 104K Zwischenblöcke gibt (ja, der Einfachheit halber lasse ich die unteren Ebenen weg). Durch Hinzufügen von 88 Bytes zu jedem der 104 KB-Blöcke werden nur 9,2 MB im Gegensatz zu 98 MB hinzugefügt.

Bedenken Sie jetzt, dass nur 5% meiner Kunden etwas getan haben. Einige machten mehr als 20 Dinge und einige weniger, so dass einige Blöcke sowieso geteilt wurden und da nur 275 KB tatsächlich benötigt wurden, um die Indexzeilen des Tages zu halten (100 k/8 * 22), ist der beste Fall, dass nur 8,9 MB meiner 9,2 MB tote Luft waren . Wenn Split-Prävention wichtig ist, ist sie 9 MB wert, ich würde jedoch härter über 98 MB nachdenken.

Wenn ich also PAD_INDEX einschalte, sollte ich die Kontrolle über Blattsplits ganz aufgeben und mich der Kontrolle über Zwischensplits widmen.

Kümmere dich nicht um irgendetwas anderes als das erste Zwischenlevel! Es gibt einen Schmetterlingseffekt, der durch Clustering (in diesem Fall Clustering von customer_number) verursacht wird und bei dem alle Berechnungen, die Sie aus dem Fenster machen, ausgelöst werden. Wenn Ihre Einfügungen nicht vollkommen gleichmäßig sind, ist Ihre Fehlerquote beim Finden der richtigen Anzahl zum Ausgleichen von Aufblähungen mit Aufspaltungen in der Regel weitaus größer als der Effekt des Blockraums auf der unteren Ebene.

7
bielawski

@bielawski Sie beschreiben nur die Fälle, in denen PAD_INDEX = ON und FILLFACTOR zwischen 1 und 99 liegen. Was denken Sie über PAD_INDEX = ON und FILLFACTOR = 0 oder 100, wenn Sie geordnete Zeilen einfügen, die immer eingefügt werden neuer als vorheriger.

CREATE CLUSTERED INDEX [IX_z_Arch_export_dzienny_pre] ON [dbo].[z_Arch_export_daily_pre]
(
    [Date] ASC,
    [Object Code] ASC,
    [From date] ASC,
    [Person_role] ASC,
    [Departure] ASC,
    [Room code] ASC,
    [period_7_14] ASC
)WITH (PAD_INDEX = ON, FILLFACTOR=100)


insert into z_Arch_export_daily_pre
select * from export_daily_pre
order by [Date] ASC,[Object Code] ASC,[From date] ASC,[Person_role] ASC,[Departure] ASC,[Room code] ASC,[period_7_14] ASC

Ich bin zu 100% sicher, dass alle neuen Zeilen "am Ende" des Index eingefügt werden, und nur mit diesen Optionen (PAD_INDEX = ON, FILLFACTOR = 100) konnte ich nach dem Einfügen 0,01% des Fragmentierungsindex erreichen. Ist etwas gefährlich bei diesen Einstellungen mit diesen Annahmen?

0
Peter_K