Die Abfrageleistung nimmt mit der Zeit und Verwendung ab

7

Ich habe seit einigen Wochen ein Problem, bei dem sich die Leistung meiner SQL Server-Abfragen über einige Tage hinweg verschlechtert. Außerdem wird eine Abfrage alle paar Tage einfach nicht vom ODBC- SQLExecute()Aufruf meiner Anwendung zurückgegeben .

Durch manuelles Neuerstellen der Indizes (in SQL Server Management Studio) werden beide Probleme "behoben".

Hier finden Sie weitere Informationen.

  • DB ist ~ 13 Gig groß
  • Verwenden von ODBC Version 3.5.1 in der App
  • Die Apps sind C ++ mit ODBC-Schnittstelle zur SQL-Datenbank
  • Testfall ist auf einer statischen DB - keine Einfügungen, daher sollte keine Fragmentierung möglich sein!
  • Kleine Abfragen dauern anfangs weniger als 1 Sekunde und werden auf über 50 Sekunden reduziert
  • Habe das Problem auf allen (3) Computern gesehen, auf denen es ausgeführt wird

Es fällt mir schwer zu verstehen, warum die gleiche Abfrage für eine Weile gut funktioniert, aber dann beginnt ich, langsamer zu werden?

Irgendwelche Ideen wären sehr dankbar.

user1825436
quelle
Ich habe eine Antwort mit ein paar Anweisungen ausgegeben, aber es würde helfen, ein paar Details zur Frage hinzuzufügen: 1.) Wie viele Zeilen in den Tabellen sind an den langsamen Abfragen beteiligt? 2.) Wie viele Einfügungen kommen in die Tabelle (n) vor? 3.) Wie viel Speicher befindet sich auf diesem Server und ist er für SQL reserviert? 4.) Wie sehen Ihre Festplatten aus? Gewidmet? Welche Art von Spezifikationen? 5.) Was passiert, wenn Sie dieselbe Abfrage in SQL Server Management Studio selbst ausführen, wenn sie langsam ist?
Mike Walsh
Vielen Dank für die tollen Vorschläge unten. Hier noch ein paar Infos.
user1825436
1) 15 Millionen Zeilen 2) 11.000 Einfügungen pro Tag 3) 24 GB auf dem Server, nicht für SQL reserviert - nur 2 GB für maximalen Speicher festgelegt. 4) Ich habe diese Informationen nicht verfügbar. 5) Ich habe das versucht - es läuft gut in SQL Mgr, während die App langsam ist. Darüber hinaus wird das Starten einer Test-App mit derselben Abfrage langsam ausgeführt. PS - Ich bin kein DBA, also entschuldigen Sie bitte meine Unwissenheit ...
user1825436
Basierend auf Ihrer Antwort auf Nummer 5 - läuft in SSMS einwandfrei, auch wenn es in der App langsam läuft. Dies sagt mir, dass es wahrscheinlich eine Kombination aus der Antwort ist, die ich in den Problemen "Abfrageplanprobleme" und "Zu viele Ad-hoc-Pläne" veröffentlicht habe. Handelt es sich um mehrere Abfragen oder nur um ein paar?
Mike Walsh
1
Update I - Wir haben die fraglichen Abfragen nur so geändert, dass sie das Parameter-Sniffing verhindern. Für jeden Parameter in der Abfrage wurden lokale Variablen deklariert (nichts mehr wurde geändert). Seitdem läuft seit 1 Woche alles recht gut. Zu früh, um den Sieg zu erklären, aber ich denke, das ist eine gute Chance. Ich werde nach mehr Zeit wieder aktualisieren und Informationen sind verfügbar.
user1825436

Antworten:

10

Abfragen können sich aus verschiedenen Gründen im Laufe der Zeit verlangsamen, und Sie können das Problem auf verschiedene Arten beheben, indem Sie die Indizes neu erstellen. Ich werde einige der häufigsten Gründe meiner Erfahrung mitteilen, aber es kann auch andere Ursachen geben. Ich vermute, Sie leiden unter einem dieser Probleme. Ich habe auch einige Fragen als Kommentar zu Ihrer Frage gestellt, um zu sehen, ob wir weitere Details erhalten können. Aber ein paar Gedanken:

Statistik Stale SQL Server verwaltet Spalten- und Indexstatistiken. Diese teilen dem Abfrageoptimierer im Wesentlichen mit, wie Ihre Daten verteilt werden. Diese Informationen sind für den Optimierer von entscheidender Bedeutung, wenn er die richtige Zugriffsmethode für Daten (Seek vs Scan) und anschließend die verwendete Verknüpfungsmethode auswählt. Wenn Sie die automatische Aktualisierungsstatistik aktiviert haben (Standardeinstellung in SQL. Auf Datenbankebene), werden diese neu berechnet, jedoch nur, wenn sich "genügend" Daten ändern. Wenn Sie also einige Einfügungen in Ihrer Tabelle haben, die Statistiken jedoch nie manuell aktualisieren und die Einfügungen / Aktualisierungen nicht ausreichen, um eine automatische Statistikaktualisierung auszulösen, leiden Sie möglicherweise unter schlechten Plänen für Ihre Datenverteilung. Durch die Neuerstellung Ihrer Indizes werden auch Ihre Indexstatistiken neu berechnet Ich würde einen Job erstellen, um Statistiken regelmäßig manuell zu aktualisieren. Dies ist ohnehin eine bewährte Methode. sp_updatestatsWenn dies das nächste Mal geschieht, versuchen Sie, es einfach in Ihrer Datenbank auszuführen und festzustellen, ob Sie einen Unterschied feststellen

Probleme mit dem Abfrageplan Möglicherweise leiden Sie unter Parameter-Sniffing. Wenn eine Abfrage zum ersten Mal ausgeführt wird, wird ein Wert übergeben. Die Abfrage wird für diesen Wert optimiert. Wenn Sie es das nächste Mal mit einem anderen Wert ausführen, der von einem anderen Abfrageplan profitieren würde, leidet es unter dem ursprünglichen Abfrageplan, was zu einer langsamen Abfrage führt. Wenn die Dinge für die App langsam laufen - sind sie auch langsam, wenn Sie dieselbe Abfrage in SQL Server Management Studio ausführen? Wenn es in SSMS schnell, in der App jedoch langsam ist, kann dies ein gutes Zeichen für das Parameter-Sniffing sein. Wenn es im Laufe der Zeit für alle Abfragen und unabhängig von den Parametern durchweg langsam ist, würde ich hier nicht nachsehen. In diesem Artikel wird viel über das Parameter-Sniffing gesprochen.

Nicht genügend Speicher / zu viele Ad-hoc-Pläne Es scheint, als würden Sie Ad-hoc-SQL an SQL Server senden. Dies kann Ihren Plan-Cache manchmal aufblähen lassen, insbesondere wenn Sie für jede Ausführung einer Abfrage einen separaten Plan haben. Abhängig vom Speicher auf Ihrem Server kann dies auch zu dem Problem führen. Wie viel Speicher befindet sich auf Ihrem Server? Schauen Sie sich diesen Link zum Problem mit Einwegplänen an. Sie haben in SQL Server 2005 nicht viele großartige Lösungen für dieses Problem, wenn Sie es haben. Wenn Sie dieses Problem in einer Umgebung ohne Produkt wiederherstellen können, würde ich empfehlen, es DBCC FREEPROCCACHEin Ihrer Umgebung ohne Produkt auszuführen, wenn dies erneut auftritt. Bitte beachten Sie! Dies ist eine instanzweite Einstellung, wenn Sie dies in der Produktion tun. Gespeicherte Abfragepläne im Cache für eine Datenbank sind nicht mehr vorhanden. Es bedeutet, dass Sie für Zusammenstellungen erneut "bezahlen" müssen. Wenn Sie eine hohe Parallelität und ein ausgelastetes System haben, kann dies zu Problemen führen. Wenn dies die einzige echte Datenbank ist und Sie ohnehin unter Leistungsproblemen leiden, schadet es nicht, dies in der Produktion zu versuchen. Wenn Sie andere Datenbanken haben und dies nur für diese Datenbank tun möchten, wird in diesem Blogbeitrag erläutert, wie Sie vorgehen müssen eine klare für nur eine DB.

Indexfragmentierung - Es ist möglich, dass die Indexfragmentierung hier das eigentliche Problem ist, aber ich bin überrascht, dass es so schnell so schlimm wird. Wenn Ihre Tabellen auf einem Schlüssel gruppiert sind, der schnell zu einer Fragmentierung führt, und Sie viele Einfügungen haben, kann dies der Fall sein. Es wäre viel schlimmer, wenn Sie in Bezug auf Speicher und Festplatten-E / A unterfordert wären. Es wäre gut, einen Job einzurichten, um Ihre Indizes regelmäßig neu zu erstellen / zu organisieren. Basierend auf Ihren Antworten auf einige Fragen in den obigen Kommentaren können andere Maßnahmen ergriffen werden, um die Auswirkungen zu minimieren.

Mike Walsh
quelle
1
+1 Ich würde auch Alternativen anbieten, um beispielsweise die Server- Optimize for ad hoc workloadsund Datenbankeinstellungen auszuprobieren parameterization forced.
Aaron Bertrand
Ich habe die Optimierung für Ad-hoc-Workloads nicht vorgeschlagen, da sie sich auf SQL Server 2005 befinden, und dies in der Antwort erwähnt. Guter Aufruf zur erzwungenen Parametrisierung.
Mike Walsh
1
Ah ja, ich habe das SQL-Server-2005-Tag verpasst. Hoffentlich sind diese Optionen für zukünftige Leser nützlich, die dieses Problem in modernen Versionen von SQL Server haben. :-)
Aaron Bertrand
+1 Ich stimme zu :-) Und vielleicht ist das ein Köder für das OP,
Mike Walsh
Ja, wir haben definitiv überlegt, auf eine moderne Version von SQL zu aktualisieren, aber wir werden dies wahrscheinlich erst tun können, wenn wir zuerst eine stabile Basislinie haben.
user1825436
5

Wir hatten das gleiche Problem mit einer unserer Produktionsdatenbanken. Allerdings eine etwas andere Situation. Die Tabellen wurden gelesen / geschrieben und enthielten ca. Über 20 Millionen Datensätze.

Wir haben die Indizes jede Woche (am Wochenende) neu erstellt, was bis zum Montagnachmittag half, und dann würde sich die Leistung aufgrund der großen Datenmenge verschlechtern.

Abhängig von der Größe Ihrer Tabelle kann es sich um Speicherprobleme handeln, bei denen dem Server nur eine bestimmte Menge an Speicherplatz für eine bestimmte Anzahl von Datensatzgruppen im Cache zur Verfügung steht. (Puffer-Cache-Trefferquote unter 90%). Lösung: Das Hinzufügen von mehr Speicher zur SQL Server-Instanz kann hilfreich sein. Dies könnte die Puffer-Cache-Trefferquote auf über 90% verbessern. Das Ergebnis ist, dass die Daten aus dem Speicher und nicht von den physischen Laufwerken abgerufen werden.

Wenn das SQL-Datenbankmodul die Abfragen "optimiert", mit denen die Daten abgerufen werden sollen, liegt möglicherweise ein Problem mit der Indexstatistik vor. (Dies war das Problem mit unserem riesigen Tisch). Die Stastiken waren veraltet. Lösung: Durch tägliches Aktualisieren der Indexstatistik für diese Tabelle können Ihre Probleme möglicherweise behoben werden.

Da Ihr Problem ein kurzfristiges Problem ist, würde ich vermuten, dass es sich um ein Problem mit der Puffer-Cache-Trefferquote (zu wenig SQL-Speicher) handelt. Das SQL Query Optimizer entfernt kleine Datensatzgruppen aus meomry, um Daten aufzunehmen, die häufiger abgerufen werden.

John aka hot2use
quelle
Danke, diese Antwort ist auch sehr hilfreich. Wir haben auch einen sehr großen Tisch, der abgefragt wird, ungefähr 15 Millionen. Ich hatte nicht versucht, mehr RAM für SQL Server zuzuweisen, werde es aber jetzt sicherlich versuchen. Das Aktualisieren der Statistiken werde ich auch tun, wenn wir das nächste Mal in diesem Zustand sind und prüfen, ob dies das Problem behebt.
user1825436
1

Ein paar Dinge fallen mir ein.

  1. Werden die ODBC-Verbindungsobjekte am Ende jeder Abfrage geschlossen und gelöscht? Andernfalls wächst der Verbindungspool weiter.

  2. Fehlen Indizes? In den dynamischen Verwaltungsansichten erfahren Sie, was dort passiert.


quelle
1) Nein, wir halten eine ODBC-Verbindung während der Lebensdauer der Apps offen. Die Anweisungscursor werden nach jeder Abfrage geschlossen. Fehlt mir bei diesem Ansatz etwas? Ich werde an dieser Stelle alle Möglichkeiten in Betracht ziehen. 2) Ich werde fehlende Indizes untersuchen, danke.
user1825436