Es kann vorkommen, dass eine kleine Datenmenge im SQL Server eine bestimmte Grenze erreicht, um einen anderen Plan oder ähnliches zu erzwingen. Dies ist nicht unwahrscheinlich. Aber die Tatsache, dass Ihre CD stark im Dienst zu sein scheint, bringt mich zu einer anderen Schlussfolgerung.
Es gibt zwei mögliche Grundgründe für Ihre Verlangsamung.
- Sie haben Ihr System aktualisiert und neu gestartet
- Sie laden eine Reihe von Daten hinein
Werfen wir einen Blick auf Teil Nr. 1
Möglicherweise ist Ihre SQL Server-Konfiguration fehlerhaft. Dies kann schwerwiegende Probleme hinsichtlich der Servergeschwindigkeit und der Disc-Nutzung verursachen.
Bitte überprüfen Sie zunächst Ihre grundlegenden Servereinstellungen. Diese Grundeinstellungen sind max server memory
, affinity I/O mask
, affinity mask
und max degree of parallelism
. Möglicherweise müssen Sie die erweiterten Optionen mit aktivieren show advanced options
.
Hier ist ein vollständiges Skript:
-- enable advanced options
EXEC sp_configure 'show advanced options',1
-- apply configuration
RECONFIGURE
-- how much memory can the sql server allocate?
EXEC sp_configure 'max server memory'
-- which cpu is used to run I/O operations
EXEC sp_configure 'affinity I/O mask'
-- which cpus can run processes?
EXEC sp_configure 'affinity mask'
-- how many threads can work on one query part?
EXEC sp_configure 'max degree of parallelism'
Vergleichen Sie das Ergebnis mit Ihren dokumentierten Werten in Ihren Installationsschritten. Sind sie immer noch gleich?
Es kann viele Gründe haben, warum sich Ihr Server so seltsam verhält. Normalerweise würde ich wetten, dass du max server memory
einfach falsch liegst. Dies führt dazu, dass Ihr SQL Server Datenseiten dauerhaft austauscht. Er kann nicht alles in Erinnerung behalten. Dies bedeutet, dass er die Seiten von der CD lesen, aktualisieren und sofort zurückschreiben muss. Wenn ein anderes Update kommt und dieselbe Seite für ein Update verwendet, kann es nicht aus dem Speicher gelesen werden. Stattdessen muss der Server es erneut von der Disc lesen. Einfach tauschen ...
Ein weiteres Problem kann eine zu hohe Affinität zu Discs oder Prozessen sein. Wenn Sie einen gemeinsam genutzten Server (SQL Server + andere Dienste) mit einer dedizierten CD für SQL Server verwendet haben (was zwar selten vorkommt, aber der Fall sein kann), könnte dies Ihr Problem sein. Ihr Server hatte normalerweise beispielsweise 3 CPU für Prozesse und einen für E / A. Die anderen 12 CPU werden für andere Dienste verwendet. In diesem Fall ist Ihre Affinitätsmaske falsch und verwendet beispielsweise eine automatische Konfiguration. Dies bedeutet, dass Ihr Server alle 16 Kerne für Prozesse und E / A dynamisch verwendet. Wenn große Prozesse ausgeführt werden, kann dies zu einer enormen Belastung der Disc führen, die möglicherweise nicht verarbeitet wird. Tatsächlich glaube ich aber nicht, dass dies Ihr Fall ist. Es wäre schneller (wenn auch nur ein bisschen), wenn dies zutreffen würde, aber Ihr Fall ist eine Verlangsamung.
Ein weiteres Problem kann ein zu hoher Grad an Parallelität sein. Dies bedeutet, dass in einem Teil einer Abfrage zu viele Threads im Leerlauf sind. Dies kann auch zu einer enormen Verlangsamung führen, wenn die Parallelität nicht wie erwartet funktioniert. Dies beschreibt jedoch nicht Ihre hohe E / A insgesamt.
Schauen wir uns jetzt auch Teil Nr. 2 an
Sie laden eine Reihe von Zeilen in Ihr System. Selbst wenn dies ein regulärer Job ist, kann dies zu einer Begrenzung führen, in der Ihre Abfragepläne eskalieren. Es kann sogar vorkommen, dass Ihre Einfügung in Kombination mit SQL Server dieses Verhalten erzeugt.
Sie haben erwähnt, dass Sie bereits versucht haben, Ihre Indizes auf eine andere CD zu migrieren, was zu helfen scheint. Dies kann nur daran liegen, dass Sie die Last auf zwei verschiedene Discs aufgeteilt haben.
Es kann sein, dass Ihre Indizes gebrochen wurden, dass Ihre Pläne gebrochen wurden oder dass Ihre Statistiken einfach veraltet sind.
1. Lassen
Sie uns die letzte Aktualisierung der Statistik überprüfen. Sie können dies manuell über die Schnittstelle für jedes einzelne Statistikelement tun. Welches wäre ein Schmerz. Oder Sie können diesen Code ausprobieren:
SELECT name AS indexname,
STATS_DATE(OBJECT_ID, index_id) AS StatsUpdated
FROM sys.indexes
Auf diese Weise erhalten Sie vollständige Informationen zu jedem Index (und Heap) und den dahinter stehenden Statistiken. Selbst wenn Sie ausführen sp_updatestats
, bedeutet dies nicht, dass die Statistiken aktualisiert wurden. Der Teil, wenn ein Update ziemlich schwierig ist, selbst wenn Sie es ausführen sp_updatestats
oder wenn auto update statistics
es aktiviert ist, werden die Statistiken nicht rechtzeitig aktualisiert. Hier sind einige Randpunkte, wenn ein Update benötigt / generiert wird:
- Eine leere Tabelle erhält eine oder mehrere Zeilen
- Eine Tabelle mit mehr als 500 Zeilen aktualisiert 20% + 500 zusätzliche Zeilen, und anschließend erfolgt eine Einfügung
- Wenn 500 Zeilen in einer Tabelle geändert wurden, die weniger als 500 Zeilen enthält
Dies bedeutet, dass Ihre Statistiken möglicherweise veraltet sind, selbst wenn Sie das Update ausführen.
Sie können sich die Abfrage oben ansehen. Wenn Sie in einigen Tabellen ziemlich alte Statistiken finden, möchten Sie möglicherweise eine manuelle Statistikaktualisierung für diese Tabelle ausführen:
UPDATE STATISTICS dbo.YourBadTable WITH FULLSCAN
Danach möchten Sie Ihrem Server vielleicht einen Tritt in den Arsch geben, um alle alten Pläne wegzuwerfen.
DBCC FREEPROCCACHE
Wenn Sie nur alle Caches bereinigen möchten, möchten Sie möglicherweise Folgendes ausführen:
DBCC FREESYSTEMCACHE ('ALL')
Dadurch werden alle Caches bereinigt, nicht nur der Plan-Cache. Normalerweise würde ich warnen, dies auf einem Produktionsserver in der Produktionsphase zu verwenden. Da Ihr Server derzeit nicht funktioniert, können Sie ihm nicht zu viel Schaden zufügen. Es kann sich für einige Sekunden verlangsamen, vielleicht 1-2 Minuten, da er alle Caches neu erstellen muss, aber danach sollte er mit den richtigen Plänen laufen.
Ein weiterer Grund können vollständig fragmentierte Indizes sein. Dies kann auf dem gesamten Server mit folgender Anweisung überprüft werden:
SELECT *
FROM sys.dm_db_index_physical_stats (NULL, NULL, NULL, NULL, NULL)
Wenn die Fragmentierung sehr hoch ist, müssen Sie sie möglicherweise neu organisieren (Fragmentierung <20%) oder vollständig neu erstellen (> 20%). Dies kann mehr Druck auf Ihre Disc ausüben und Probleme verursachen. Auf der anderen Seite, wenn die Indizes so schlecht sind, würde es am Ende wahrscheinlich mehr helfen, als es schadet.
Neben diesen beiden Gründen kann es noch ein drittes Problem geben
Möglicherweise ist Ihr Server konfiguriert, Sie haben in dieser Zeit keinen Code geändert, sondern nur ein paar Zeilen hinzugefügt. Alle Statistiken werden aktualisiert und alle Caches werden neu erstellt. Alle Ihre Indizes werden so neu organisiert, wie Sie sie benötigen, aber dennoch - nichts funktioniert. Möglicherweise haben Sie in Ihren Prozessen die Grenze des verfügbaren Speichers erreicht. Vielleicht brauchst du mehr. Sie können einfach überprüfen, ob es einen Prozess gibt, der versucht, mehr Speicher als Sie zu erhalten.
Sie können dies mit diesem Befehl überprüfen:
SELECT * FROM sys.dm_exec_query_memory_grants
Sie erhalten eine Liste aller Sitzungen, die Speicher verbrauchen. Möglicherweise wartet eine Abfrage noch auf den Speicher. Diese Abfragen können leicht gefiltert werden. Alle Sitzungen wo granted_memory_kb IS NULL
. Dies sind Sitzungen, die Speicher angefordert haben, diesen aber nicht erhalten. Eine andere Sache kann ein gewährter Speicher sein, der zu niedrig sein kann. Sie können die Spalten requested_memory_kb
mit vergleichen granted_memory_kb
. Angefordert zeigt an, wie viel Speicher der Prozess benötigt, um optimal ausgeführt zu werden, während er gewährt wird. Der für den Prozess aktivierte Speicher wird angezeigt. Wenn ein Prozess 2 GB benötigt, um ausgeführt zu werden, aber nur 2 MB erhält, erhalten Sie ihn möglicherweise selbst. ;-);
Eine andere Möglichkeit besteht darin, Folgendes zu überprüfen RESSOURCE_SEMAPHORE
:
SELECT * FROM sys.dm_exec_query_resource_semaphore
Sie können sich das waiter_count
und das ansehen grantee_count
. Wenn der Kellner über 0 liegt, haben Sie Druck auf Ihr Gedächtnis, was zu einem Austausch und dem von Ihnen im Perfmon beobachteten Scheibendruck führen kann.