Wir haben eine große Datenbank (ca. 1 TB), in der SQL Server 2014 auf einem leistungsstarken Server ausgeführt wird. Für ein paar Jahre hat alles gut funktioniert. Vor ungefähr 2 Wochen haben wir eine vollständige Wartung durchgeführt, die Folgendes beinhaltete: Alle Software-Updates installieren; Erstellen Sie alle Indizes und kompakten DB-Dateien neu. Wir hatten jedoch nicht erwartet, dass die CPU-Auslastung der DB zu einem bestimmten Zeitpunkt um über 100% auf 150% anstieg, wenn die tatsächliche Auslastung gleich war.
Nach einer Menge Fehlerbehebung haben wir es auf eine sehr einfache Abfrage eingegrenzt, aber wir konnten keine Lösung finden. Die Abfrage ist denkbar einfach:
select top 1 EventID from EventLog with (nolock) order by EventID
Es dauert immer ca. 1,5 Sekunden! Eine ähnliche Abfrage mit "desc" dauert jedoch immer ungefähr 0 ms:
select top 1 EventID from EventLog with (nolock) order by EventID desc
PTable hat ungefähr 500 Millionen Zeilen; EventID
ist die primäre gruppierte ASC
Indexspalte ( geordnet ) mit dem Datentyp bigint (Identitätsspalte). Es gibt mehrere Threads, die Daten in die Tabelle oben einfügen (größere EventIDs), und es gibt einen Thread, der Daten von unten löscht (kleinere EventIDs).
In SMSS haben wir überprüft, dass die beiden Abfragen immer denselben Ausführungsplan verwenden:
Clustered Index Scan;
Geschätzte und tatsächliche Zeilennummern sind beide 1;
Geschätzte und tatsächliche Anzahl der Hinrichtungen sind beide 1;
Geschätzte I / O-Kosten sind 8500 (scheint hoch zu sein)
Bei fortlaufender Ausführung betragen die Abfragekosten für beide die gleichen 50%.
Ich habe die Indexstatistik aktualisiert with fullscan
, das Problem blieb bestehen. Ich habe den Index erneut erstellt, und das Problem schien einen halben Tag lang nicht mehr zu bestehen, kam aber zurück.
Ich habe die E / A-Statistik aktiviert mit:
set statistics io on
Dann wurden die beiden Abfragen nacheinander ausgeführt und die folgenden Informationen gefunden:
(Für die erste Abfrage, die langsame)
Tabelle 'PTable'. Scan-Anzahl 1, logische Lesevorgänge 407670, physische Lesevorgänge 0, Vorauslesevorgänge 0, logische Lobs-Lesevorgänge 0, physische Lobs-Vorauslesevorgänge 0.
(Für die zweite Frage, die schnelle)
Tabelle 'PTable'. Scananzahl 1, logische Lesevorgänge 4, physische Lesevorgänge 0, Vorauslesevorgänge 0, logische Lobs-Lesevorgänge 0, physikalische Lobs-Lesevorgänge 0, Lobs-Vorauslesevorgänge 0.
Beachten Sie den großen Unterschied bei den logischen Lesevorgängen. Der Index wird in beiden Fällen verwendet.
Indexfragmentierung könnte ein wenig erklären, aber ich glaube, die Auswirkung ist sehr gering. und das Problem ist noch nie passiert. Ein weiterer Beweis ist, wenn ich eine Abfrage wie folgt ausführe:
select * from EventLog with (nolock) where EventID=xxxx
Auch wenn ich xxxx auf die kleinsten EventIDs in der Tabelle gesetzt habe, ist die Abfrage immer blitzschnell.
Wir haben es überprüft und es gibt kein Problem mit dem Sperren / Sperren.
Hinweis: Ich habe gerade versucht, das Problem oben zu vereinfachen. Die "PTable" ist eigentlich "EventLog"; das PID
ist EventID
.
Ich bekomme das selbe Testergebnis ohne den NOLOCK
Hinweis.
Kann jemand helfen?
Detailliertere Abfrageausführungspläne in XML wie folgt:
https://www.brentozar.com/pastetheplan/?id=SJ3eiVnob
https://www.brentozar.com/pastetheplan/?id=r1rOjVhoZ
Ich denke nicht, dass es wichtig ist, die Anweisung create table bereitzustellen. Es ist eine alte Datenbank und läuft seit langer Zeit bis zur Wartung einwandfrei. Wir haben selbst viel recherchiert und es auf die in meiner Frage angegebenen Informationen eingegrenzt.
Die Tabelle wurde normalerweise mit der EventID
Spalte als Primärschlüssel erstellt, bei der es sich um eine identity
Typspalte handelt bigint
. Zu diesem Zeitpunkt liegt das Problem vermutlich bei der Indexfragmentierung. Unmittelbar nach der Indexwiederherstellung schien das Problem einen halben Tag lang nicht mehr zu bestehen. aber warum kam es so schnell zurück ...?