2016-04-11 5 views
1

Nehmen wir an, wir haben ein OLTP-System mit SQL Server. Nehmen wir an, wir haben einen Clustered-Index für eine Tabelle.Warum sollten Sie fillfactor in dieser Situation auf einen niedrigen Wert setzen?

Bitte geben Sie mir einige Antworten auf die folgenden Fragen:

Wenn Sie nur neue Datensätze einfügen, die den Index, um zu folgen, dann würde die Seitenteilung nur auf den Seiten begrenzt werden - bei oder nach - die letzte Seite, die bestanden Zum Zeitpunkt der letzten Indexneuerstellung, richtig? Wenn Sie nur neue Datensätze einfügen, die der Indexreihenfolge folgen, wird auf keiner Seite jemals eine Seitenaufteilung auftreten, die sich vor der Reihenfolge der letzten Seite befindet, die zum Zeitpunkt des letzten Indexes existierte umbauen, richtig?

Das heißt, solange Sie nicht versuchen, Datensätze in die Mitte des vorhandenen Index einzufügen, werden Sie nie eine Seitenaufteilung auf einer Seite verursachen, die sich vor der letzten Seite befindet, die zur Zeit Ihrer Existenz existiert letzter Index neu aufgebaut, korrekt?

Wenn das obige alles wahr ist, stimmt es dann auch nicht, dass Sie es normalerweise vermeiden, Datensätze in die Mitte eines vorhandenen Indexes einzufügen? Ich meine, wann würdest du so etwas machen wollen?

Ich stelle diese Fragen, weil ich nicht genau verstehen kann, warum jemand einen Füllfaktor auf einen niedrigen Wert für einen Index auf einem OLTP-System festlegen würde. Meine Gedanken sind: "Wenn Sie nicht vorhaben, den Index durch Einfügen von Datensätzen in die Mitte des vorhandenen Index zu durcheinander zu bringen, dann sollten Sie den gesamten ungenutzten leeren Speicherplatz in jeder Indexseite und Datenseite reservieren, wenn er nie gefüllt wird oben?"

Ich verstehe, dass Seitenaufteilungen ab der letzten Seite (Reihenfolge) - die zum Zeitpunkt der letzten Indexerstellung existierte - abgehen. Aber können Sie näher erläutern, warum jemand fillfactor auf einen niedrigen Wert für ein OLTP-System festlegen würde, wo Sie keine Datensätze in die Mitte des vorhandenen Index einfügen möchten?

Wenn mir etwas in meinem Verständnis fehlt, wie das alles funktioniert, lass es mich auch wissen.

Danke.

+0

ist es gut, das gleiche auf DBA .SE zu fragen – TheGameiswar

Antwort

1

Ihr Verständnis von entspricht meinem Verständnis.

Wenn das obige alles wahr ist, ist es dann nicht auch wahr, dass Sie es normalerweise vermeiden, Datensätze in die Mitte eines vorhandenen Indexes einzufügen? Ich meine, wann würdest du so etwas machen wollen?

Wenn Sie keinen sequenziellen Schlüssel verwenden. Wenn alle Clusterindizes IDENTITY(1,1) Felder sind, dann sicher. Dies ist jedoch wahrscheinlich nicht für jede Tabelle in Ihrer gesamten Datenbank. Wenn Sie Junction-Tabellen für Viele-zu-Viele-Beziehungen haben, können Sie jederzeit Beziehungen hinzufügen. Sie probably wollen nicht, dass die Tabelle einen IDENTITY(1,1)10 Schlüssel in dieser Tabelle überhaupt hat. Wenn Sie stattdessen einen zusammengesetzten Primärschlüssel der Fremdschlüssel in der Tabelle gruppieren, weil Sie bei der Verknüpfung nicht mehr die sequenziellen Einfügungen verwenden.

Darüber hinaus, auch wenn Sie verwenden, auch wenn Sie sequenzielle Schlüssel verwenden, könnten Sie nicht Cluster auf ihnen. Es ist möglich und oft wünschenswert, sich auf etwas anderes als die IDENTITY-Spalte zu konzentrieren. Das hängt davon ab, wie Sie Ihre Daten verwenden möchten.Wenn Sie Ereignisse speichern, aber wissen, dass Sie Ereignisse von jeder Site zusammenhalten möchten, weil Sie auf diese Weise Ereignisse in 90% der Fälle abfragen, können Sie die Ereignissite in den Clustering-Schlüssel aufnehmen.

1

Ein etwas kompliziertes Szenario wäre, wenn Zeilensperren zu Seitensperren eskalieren, weniger Zeilen betroffen sind, da es weniger Zeilen pro Seite gibt. Wenn jedoch keine DML stattfindet, sollten alle Sperren gemeinsame Sperren sein und damit kompatibel sein.

Ein anderes Szenario wäre, wenn Sie eine Zeile so aktualisieren, dass sie nicht mehr auf die Seite passt. Stellen Sie sich die folgende Tabelle:

create table foobar (
    a int identity primary key clustered, 
    b varchar(1000) default 'a' 
); 

Nun, wenn ich tun:

insert into foobar default values 
go 1000 

ich alle diese Zeilen auf einer Seite bekommen könnte (mehr oder weniger - unter der Annahme, dass der Füllfaktor 100 ist, jede Zeile wird 4 + 1 = 5 Bytes aufnehmen Ich weiß, dass es einen Zeilenoverhead gibt, aber machen wir die Demo einfach. Aber was, wenn ich tun:

update foobar 
set b = replicate('a', 1000); 

Jetzt nimmt jede Zeile bis 4 + 1000 = 1004 Bytes und ich kann nur passen ≈ 7 Zeilen pro Seite. Ich brauche viel mehr Seiten! Aber wenn der Füllfaktor anfänglich niedriger gesetzt worden wäre, würde ich wahrscheinlich immer noch einige Seitenaufteilungen machen (es sei denn, der Füllfaktor wurde so eingestellt, dass es nur eine Zeile/Seite gab), aber weniger von ihnen. Wenn Sie mit SQL 2008 oder höher arbeiten, lade ich Sie dazu ein, dies mit erweiterten Ereignissen zu erkunden - es gibt ein Ereignis für Seitenaufteilungen.

TL, DR - Updates können auch Seitenaufteilungen verursachen.

1

Ja, wenn das Anhängen an einen Index-Füllfaktor nicht hilft.

Ja, das Schreiben in die Mitte eines Indexes in einer Weise, die Seitenaufteilungen verursacht, ist keine gute Sache.

Sie können nicht immer an einen Index anhängen. Wenn Sie Benutzerregistrierungen für ein Webforum indizieren, geben Benutzer eine zufällige Reihenfolge ein: E-Mail, Benutzername, Telefon, E-Mail-Aktivierungsschlüssel. (Es wird auch sequenzielle Einfügungen wie ID und Registrierungsdatum geben.)

Hier ist nur die Wahl, wie (wenn überhaupt) zu mildern ist.

Warum würde jemand fillfactor auf einen niedrigen Wert für ein OLTP-System festlegen, wo Sie keine Datensätze in die Mitte des vorhandenen Index einfügen möchten?

Ich würde das zwar nicht tun, aber solch ein reines OLTP-System existiert selten.

Es ist eine Sache von Indizes, Daten in einer anderen Reihenfolge darzustellen. Nicht alle interessanten Aufträge sind aufeinander abgestimmt.

Verwandte Themen