Wenn ich eine Abfrage teste, lasse ich in der Regel die folgenden Zeilen vor allem, was ich teste, um sicherzustellen, dass ich jedes Mal, wenn ich eine Abfrage durchführe, von der gleichen Basislinie aus starte.
%Vor%Bei dem Stored-Proc, den ich heute lief, fiel mir auf, dass es, wenn ich mit diesen Zeilen rannte, jedes Mal ungefähr 18 Minuten dauerte. Als ich diese Zeilen wegließ, dauerte es nur 3. Als ich den drastischen Unterschied sah, der durch einen geclearten Cache gegenüber einem geprimten Cache verursacht wurde, habe ich folgendes hinzugefügt, um zu sehen, ob ich den Cache manuell starten konnte Performance.
%Vor% Wie Sie vielleicht schon vermutet haben, verwendet sp_MyProc
Table1
ziemlich oft. Ich war überrascht zu sehen, dass dies meine Laufzeit auf 6 Minuten reduziert hat. Obwohl es die Leistung verbessert, sieht es ein wenig hackisch aus, und ich bin neugierig, ob etwas in SQL Server eingebaut ist, das dies erreichen wird.
Wenn mein Verständnis von Caching etwas zu kurz ist, können Sie gerne Links oder Informationen weiterleiten, die Ihrer Meinung nach hilfreich sein könnten.
UPDATE: Nun, es ist mir peinlich zu sagen, dass ich versucht habe, dieses Verhalten heute zu reproduzieren, konnte es aber nicht. Ich habe mit einigen Leuten bei meiner Arbeit gesprochen und es sieht so aus, als ob einige der Sachen, die sie gestern in der DB gemacht haben, es so aussehen ließen, als ob meine Auswahl vor der Proc Performance verbessern würde, obwohl es in Wirklichkeit nicht war. Ich würde immer noch interessiert sein zu hören, ob jemand weiß, ob das "Auffüllen" des Caches durch möglich ist.
Ich gebe eine "Antwort", um zu versuchen, das durchzuarbeiten, denn das interessiert mich besonders.
Ich stieß auf diesen MSDN-Artikel darüber, wie Sie sehen können, was sich im SQL Server-Cache befindet . Dort gibt es eine Abfrage, die Ihnen zeigt, wie viele Datenseiten nach Objekt gecacht werden - ich habe es optimiert, um den Indexnamen wie folgt einzuschließen:
%Vor%Wenn Sie die folgenden Schritte ausführen, sollten Sie in der Lage sein zu sehen, was im Hinblick auf das Zwischenspeichern vor sich geht. Tun Sie dies in Ihrer Datenbank (im Gegensatz zu beispielsweise Master):
1) Checkpoint + Löschen des Caches nach unten
2) Führen Sie die obige Abfrage und Sie erhalten wahrscheinlich erhalten 1 Datensatz zurückgegeben (für sysobjvalues), aber nichts für Table1
3) Führen Sie jetzt die SELECT TOP 1 '1' FROM MyTable
Anweisung aus
4) Führen Sie die obige Abfrage erneut aus und sehen Sie, was jetzt in den Ergebnissen angezeigt wird - Sie werden wahrscheinlich Datensätze für MyTable sehen, die zwischengespeicherte Seiten anzeigen - notieren Sie sich diese Nummer
Dies sollte Ihnen einen Hinweis auf die Ebene der Daten-Caching geben, die für diese erste SELECT erfolgt. Wenn Sie den Vorgang wiederholen, aber statt der Anweisung SELECT TOP, führen Sie Ihren Sproc aus und sehen dann, wie viel im Cache gelaufen ist, wenn er ausgeführt wird. Wenn Sie diese Ergebnisse vergleichen, wird der relative Caching-Anteil angezeigt SELECT TOP 1 im Vergleich zum SPROC-Aufruf - und dieser relative Betrag könnte die Leistungsverbesserung anzeigen.
Das ist sehr viel "Nachdenken" Zeug. Ich hätte nicht gedacht, dass die TOP 1 den Cache wirklich für den Sproc-Aufruf stark vorbereitet hätte, aber darum interessiere ich mich für diese Frage!
Ich hätte anfangs gedacht, dass es mehr mit anderen Faktoren zu tun hat (z. B. Server- / Plattenlast). Sie könnten nacheinander zwischen den 2 Szenarien für 3 oder 4 Iterationen wechseln, um zu überprüfen, ob der SELECT TOP-Ansatz tatsächlich konsistent besser ist (helfen Sie dabei, das Risiko eines einmaligen Blips zu minimieren).
Hoffe, das hilft / bringt den Ball ins Rollen.
Aktualisierung:
Jetzt wissen Sie, dass es nicht der SELECT TOP ist, der den Cache auflädt, ein guter Weg, den Cache zu primen, wie AdrianBanks sagte. Zumindest können Sie jetzt erklären, was den Leistungsunterschied unerwartet / verwirrend war! Bewahren Sie das obige Skript in Ihrer Bibliothek auf. Es ist nützlich, um den Status des Caches zu überprüfen.
Ihr Update auf Ihre Frage stimmt mit dem überein, was ich erwarten würde. Ich kann nicht sehen, wie das Ausführen der SELECT 1...
-Abfrage bei der nachfolgenden Abfrage einen wirklichen Leistungsvorteil haben könnte.
Wie ich es verstehe, lädt SQL Server Datenseiten (die entweder Tabellendaten oder Indexdaten enthalten) in den Speicher, wenn sie sie beim Ausführen von Abfragen benötigen. Diese werden im Speicher gehalten, es sei denn, sie werden explizit gelöscht (mit DBCC DROPCLEANBUFFERS
- dh alle Puffer (zwischengespeicherte Seiten) im Speicher, die seit dem Laden nicht verändert wurden), oder es gibt Speicherdruck (entweder wenig freier Speicher auf dem Rechner oder ein maximaler Speicher, der auf SQL Server festgelegt wird). Aufgrund dieses Verhaltens kann es von Vorteil sein, eine SQL Server-Datenbank zur Verwendung aufzuwärmen. Wenn Sie anschließend eine Abfrage ausführen, befinden sich die zum Erfassen der Abfrageergebnisse erforderlichen Daten möglicherweise bereits im Speicher. Wenn dies der Fall ist, wird die Abfrage schneller ausgeführt, da weniger IO benötigt wird.
Das Problem besteht jedoch darin, zu wissen, was vorzucachen ist und welche Abfragen ausgeführt werden sollen. Sie können eine SQL-Ablaufverfolgung für typische Aktivitäten ausführen und sie dann erneut zum Zwischenspeichern von Daten verwenden, die häufig verwendet werden. Ohne dass SQL Server eine große Menge an zugewiesenem Speicher bereithält, müssen Sie immer einige Dinge von der Festplatte lesen (es sei denn, Sie haben eine kleine Datenbank). Da Sie nie wissen werden, was zwischengespeichert ist und was nicht, fühlt sich das Verhalten für die Leistung falsch an.
Ich würde meine Bemühungen darauf konzentrieren, die Abfragen effizienter zu gestalten, indem ich weniger Daten lese oder möglichst Indizes verwende. Das gibt Ihnen auch allgemeine Vorteile sowie eine bessere Leistung von Kaltstarts.
Eine Möglichkeit, den SQL Server-Cache für vollständige Tabellendaten (oder Teilmengen davon) zu primen, besteht darin, Folgendes auszuführen:
SELECT SUM(CAST(BINARY_CHECKSUM(*) AS BIGINT)) FROM my_table
Dies bewirkt, dass alle Spalten für eine Tabelle von der Platte gelesen werden, gibt aber ein kleines Ergebnis zurück, das inkrementell von SQL berechnet werden kann. Der SQL-Optimierer wird dies nicht tun, wenn Sie COUNT
oder ähnliche Abfragen zum Starten des Caches verwenden, da diese nur durch Laden von Indexseiten beantwortet werden können.
Passen Sie die Spalten an und fügen Sie WHERE
-Klauselanweisungen hinzu, um Indizes oder Tabellensubsets nach Bedarf zu cachen.
Tags und Links sql-server sql-server-2005 caching