Würde ein Tisch davon profitieren, wenn es ein Haufen wäre?

7

Ich habe eine Protokollierungstabelle mit ca. 1.500.000 Zeilen, der Primärschlüssel ist eine aufsteigende Identität und der Clustered-Index befindet sich auf dem Primärschlüssel. Der Identitätswert wird automatisch generiert => Datensätze werden immer am Ende hinzugefügt. Die durchschnittliche Zeilengröße beträgt 1570 Byte.

Es gibt viele Seitenteile, da häufig neue Zeilen hinzugefügt werden. Keine Zeilen werden aktualisiert / gelöscht und es gibt einen nicht gruppierten Index für die Tabelle, sodass Zeilen ausgewählt werden können. Aufgrund der Seitenteilung ist der Clustered-Index immer zu> 65% fragmentiert.

Ich frage mich, ob meine Tabelle davon profitieren würde, den Clustered-Index zu entfernen und daraus eine Heap-Tabelle zu machen.

So sieht meine Tabelle + nicht gruppierter Index aus:

CREATE TABLE [dbo].[LogEntry](
[Id] [bigint] IDENTITY(1,1) NOT NULL,
[Application] [varchar](20) NOT NULL,
[EntityFullName] [varchar](80) NOT NULL,
[Action] [int] NOT NULL,
[UserName] [varchar](25) NOT NULL,
[TimeStamp] [datetime] NOT NULL,
[EntityId] [varchar](50) NOT NULL,
[WhatChanged] [nvarchar](max) NULL,
CONSTRAINT [PK_LogEntry] PRIMARY KEY CLUSTERED(     
   [Id] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 100) ON [PRIMARY] ) 
ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]


CREATE NONCLUSTERED INDEX [ID_Application_Entity_FullName_TimeStamp] ON [dbo].[LogEntry]
(
    [Application] ASC,
    [EntityFullName] ASC,
    [TimeStamp] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = OFF) ON [PRIMARY]
GO

Update: Jemand hat das automatische Schrumpfen hinter meinem Rücken aktiviert => Dies ist die Ursache für die Fragmentierung

Frederik Vanderhaegen
quelle
Wenn in dieser Tabelle nicht viele Scans und Lesevorgänge ausgeführt werden, können Sie die Spalte nvarchar (max) außerhalb der Zeile speichern. Ich bin mir nicht sicher, warum Sie ohne Updates fragmentiert werden. sp_tableoption N'MyTable ',' große Werttypen außerhalb der Zeile ',' ON '
Chad Mattox
Wenn die Protokolleinträge hinzugefügt werden, werden sie in Bündeln oder durch parallele Prozesse hinzugefügt? Der Identitätswert wird erstellt, bevor die Zeile auf die Festplatte geschrieben wird, und ist eine mögliche Ursache für die Fragmentierung.
AlwaysLoadingData

Antworten:

5

Dies begann als Kommentar / Fragen, aber es wurde zu lang, also habe ich es hierher verschoben:

Diese Frage wirft mich wirklich auf. 1,5 mil Reihen sind nicht wirklich so groß. Und der Punkt hinter einer Identität ist, dass sie immer größer wird. Wenn dies Ihr CL ist, sollten Sie keine Einfügungen in die Mitte einer Seite vornehmen, sicherlich nicht oft genug, um den Grad der Fragmentierung zu verursachen, den Sie sehen.

Einige Fragen:

Machst du IDENTIY_INSERTS? Grundsätzlich angeben, wie hoch der Identitätswert sein soll? Oder haben Sie die Identität irgendwann zurückgesetzt, sodass Sie sie in die Mitte des Bereichs einfügen?

Wenn Sie Einfügungen vornehmen, sieht dies normalerweise folgendermaßen aus:

5 6 7 8 < Next insert goes here >

Aber wenn Sie so etwas haben (nehmen Sie an, Ihr nächster Identitätswert ist 4)

 1 2 3 < Next insert goes here > 100 101  

Dann könnten Sie einige Seitenaufteilungen sehen. Aber im normalen Verlauf der Dinge sollten Sie nicht sein.

Gibt es eine Chance, dass Sie Ihre Datenbank verkleinern? Auto_shrinkoder ein Wartungsplan / Job, der schrumpft? Wenn ja, ist es der Schrumpf, der Ihre Fragmentierung verursacht, nicht der Clustered-Index.

Im Allgemeinen ist an einem HEAP nichts auszusetzen und sie können für INSERTs schneller sein. Meine größte Sorge mit ihnen ist in der Regel, wenn Sie eine große Anzahl von Löschungen oder Aktualisierungen durchführen (von denen Sie sagen, dass Sie dies nicht tun). In diesen Fällen kann es zu einem Speicherplatzleck kommen und eine Tabelle mit mehreren GB Größe und 0 Zeilen erhalten.

Aktuelle Antwort

Wenn Sie über eine Protokolldatei verfügen und diese immer nur einfügen, können Sie versuchen, die PK zu löschen und zu sehen, wie sich die Leistung entwickelt (natürlich zuerst in einer Testumgebung). Sobald Sie einige Tests mit Ihrer Arbeitslast durchgeführt und gesehen haben, wie die Dinge laufen, nehmen Sie Ihre Änderungen in der Produktion vor und überwachen Sie sie dort für eine Weile. Sie könnten sogar in Betracht ziehen, die Identitätsspalte vollständig zu löschen.

Überprüfen Sie das SHRINK-Ding. Das ist ein Mörder.

Kenneth Fisher
quelle
Ich frage mich, ob es in der Spalte Identität einen MAX-Wert gibt, der höher ist als der zuletzt eingefügte Identitätswert. (Das Verständnis, dass max, höher und so weiter davon abhängt, was die Samen und Inkremente in der Vergangenheit waren). Und ich bin auch mit Ihnen zusammen. Ich kenne keinen Grund, diese PK auf diesem Tisch zu haben, natürlich mit einer ganzen Reihe von Annahmen. Ich würde auch sagen, dass es im Trend liegt, diese Art von Daten nicht einmal in eine Tabelle zu schreiben.
Karen Lopez
1
Wenn der Clustered-Index DESCENDING erstellt wird, befinden sich die Einfügungen ständig am Anfang des Index, was sich auch auf die Fragmentierung auswirken kann (??).
Am
Bitte beachten Sie auch, dass INSERTHeaps bei einzelnen s ihre Seiten nicht so vollständig füllen wie Clustered-Tabellen. Und ich bin damit einverstanden, dass hier etwas los ist, das aus den bereitgestellten Informationen nicht ersichtlich ist, also +1, um auf Ermittlungen zu drängen, bevor Änderungen vorgenommen werden :-).
Solomon Rutzky
1
@ AMtwo Yep. Beispiel dafür hier stackoverflow.com/questions/743858/…
Martin Smith
1

Es könnte interessant sein, die Einstellungen von Thomas Kejser zu Indizes in SQL Server zu überprüfen. Obwohl Clustered-Indizes sehr nützlich sind, kann es Gründe geben, einen Heap zu behalten. Lesen Sie zum Beispiel diesen Beitrag:

http://kejser.org/clustered-indexes-vs-heaps/

Schauen Sie sich insbesondere das Thema an: Fragmentierung Anfällige Tabellen mit vielen INSERT-Aktivitäten

Dieses Thema scheint genau das Problem zu beschreiben, mit dem Sie bei der Fragmentierung konfrontiert sind. Damit...

Betrachten Sie die Alternative: Eine Indizierungsstrategie, bei der Sie einen ausreichend „zufälligen“ Schlüssel (wie eine GUID) auswählen und diesen Schlüssel nicht blind als Clusterindex deklarieren, sondern die Tabelle als Heap belassen und einfach ein gutes, altmodisches, eindeutiges Non setzen -clustered Schlüsselindex auf der GUID . Der Großteil des Tabellenwachstums von INSERTs geht jetzt auf den Haufen, der sich gut füllt und nicht fragmentiert bleibt.

Ein weiterer Kommentar von technet: http://technet.microsoft.com/en-us/library/hh213609.aspx

"Manchmal verwenden Datenarchitekten Heaps, wenn auf Daten immer über nicht gruppierte Indizes zugegriffen wird und die RID kleiner als ein gruppierter Indexschlüssel ist."

Diese Beiträge geben Ihnen möglicherweise Anlass zum Nachdenken über Ihr Problem.

RLF
quelle
3
Interessanterweise hat @aaronbertrand einen Geschwindigkeitstest für Rid-Lookups im Vergleich zu Key-Lookups durchgeführt, obwohl er auf YMMV hingewiesen hat. t.co/MdaktFpbnz Auch (in diesem Fall kein Problem), aber Sie müssen auf Haufen achten , auf denen Sie viele Löschvorgänge ausführen. Sie können mit einem Raumleck finden. Ich habe eine Tabelle, die häufig mehrere GB w 0 Zeilen belegt.
Kenneth Fisher
-5

Der FILLFACTOR in der Tabelle ist 100, daher enthält der Cluster-Index keine freien Seiten. Wenn Sie viele Einfügungen vornehmen, versuchen Sie, FILLFACTOR auf etwa 80 einzustellen. Lesen Sie auch die SQL Server-Bücher online zu FILLFACTOR. ;-);

Jason Kohlhoff
quelle
2
Für den in der Frage der Einfügungen in einen immer größer werdenden Schlüssel und ohne Aktualisierungen beschriebenen Anwendungsfall wäre dies nur Platzverschwendung.
Martin Smith
Fillfactor ist kein Problem (nur Einfügungen der letzten Seite aufgrund des Identitätsschlüssels), Autoshrink war das Problem
Frederik Vanderhaegen