2 Stimmen

Wie können falsche SQL-Statistiken dazu führen, dass eine Anfrage an einer 40-Zeilen-Tabelle über eine Minute dauert?

Nachdem ich zwei Stunden lang versucht hatte herauszufinden, warum meine (ziemlich einfache) SQL-Abfrage auf ein paar ziemlich leeren Ansichten über eine Minute dauerte, führte ich schließlich ein "Update-Statistiken" auf den betroffenen Ansichten durch und meine Abfrage ging sofort auf ein akzeptableres Ergebnis herunter.

Das gesagt habend, finde ich das Ganze mit den Statistiken ein wenig seltsam, wenn man bedenkt, dass :

  • die drei betroffenen Ansichten früher über 10000 Zeilen zurückgaben und die zugrunde liegenden Tabellen gerade abgeschnitten wurden, sodass die Ansichten nur 40, 60 und 60 Zeilen hatten (die zugrunde liegenden Tabellen haben ungefähr die gleiche Anzahl von Zeilen)
  • ein select * auf den drei betroffenen Ansichten eine sofortige Operation ist
  • die manuelle Verknüpfung (wie in einem Excel-Blatt) wahrscheinlich schneller gewesen wäre als auf den SQL-Server zu warten, um die Verknüpfung zu berechnen !!
  • und, last but not least, die gleiche Anfrage auf einem anderen Server mit dem gleichen Schema, über 10000 Zeilen und aktuellen Statistiken praktisch sofort erfolgt.

Ich verstehe, wie schlechte Statistiken zu einem suboptimalen Ausführungsplan führen können. Was ich nicht verstehe, ist, wie diese schlechten Statistiken zu einem so suboptimalen Ausführungsplan führen können.

Ich benutze SQL Server 2008.

Bearbeitung: Leider kann ich hier keine Ausführungspläne oder tatsächlichen Definitionen hinzufügen. Was ich suche ist eher eine Erklärung dafür, "wie schafft es der SQL Server, 1 Minute zu brauchen, um 3 Tabellen mit weniger als hundert Zeilen in jeder zu verknüpfen, selbst mit falschen Statistiken", anstatt "wie kann ich mein spezifisches Problem lösen", was dank des von mir durchgeführten Update der Statistiken bereits erledigt ist.

3voto

Chris J Punkte 29515

Es gibt einen guten Überblick hier auf sql-server-performance.com (auch wenn er für SQL 2000 geschrieben wurde, aber die grundlegenden Konzepte dürften sich nicht geändert haben, auch wenn die Details sich geändert haben).

Es ist etwas, das ich schon gesehen habe, wenn eine Datenbank viele Zeilen aus Tabellen entfernt hatte und die Auto-Statistik ausgeschaltet war. Die Statistiken sagen SQL Server die ungefähre "Verbreitung" der Daten und haben einen direkten Einfluss auf den Optimierer, da sie verwendet werden, um zu bestimmen, welche Indizes verwendet werden, um eine Abfrage zu erfüllen, und welche physischen Operationen verwendet werden, um einen Join zu erfüllen.

Die effizienteste physische Join-Operation kann von aktuellen Statistiken abhängen, und die Verwendung des falschen Operators kann ziemlich katastrophale Auswirkungen haben. Ebenso kann es sich entscheiden, faules Spooling durchzuführen, wenn es nicht notwendig ist (usw.). Als ich dieses Verhalten gesehen habe, habe ich beobachtet, wie SQL Server Parallelismus mit einigen seltsamen Indexoptionen eingeleitet hat, um nur einige Hundert Zeilen zu verarbeiten.

0voto

KristoferA Punkte 12049

Es ist nicht wichtig, wie viele Datensätze von den beteiligten Ansichten zurückgegeben werden. Der interessante Teil ist: wie viele Datensätze befinden sich in den zugrunde liegenden Tabellen? Für normale Ansichten wird der SQL Server sie beim Kompilieren des Abfrageplans erweitern, sodass anstelle des Ausführens jedes einzelnen eine große neue Ausführungsplan erstellt wird, als ob das, was in den Ansichten gemacht wird, Teil Ihrer Abfrage ist...

0voto

Janet Punkte 1

Ich denke, dies ist ein Fehler mit SQL Server 2008, denn ich habe das selbst oft bemerkt und musste nie manuell Statistiken mit früheren Versionen von SQL Server aktualisieren. Oft habe ich Abfragen in neueren Versionen von SQL Server, die eine Weile extrem schnell funktionieren, dann plötzlich scheitern. Hier ist ein Beispiel für eine Abfrage, die Sekunden dauert und plötzlich nicht mehr funktioniert - sie wird tagelang hängen und nicht beendet. Ich habe schließlich herausgefunden (nach viel Zeit und Mühe), dass alles, was ich tun muss, ist, manuell die Statistiken auf der KLEINSTEN Tabelle zu aktualisieren, und die Leistung normalisiert sich wieder. Also läuft dies reibungslos für mehrere Produktionsläufe und plötzlich funktioniert es nicht mehr (keine Code-Änderungen, keine Datenänderungen), dann aktualisiere ich manuell die Statistiken und alles geht wieder normal. Ich habe das Gefühl, dass ich jetzt mit Oracle arbeite - Code, der in Sekunden funktionierte, dauert plötzlich ewig - analysiere alle Tabellen und es ist behoben. Ich habe das Gefühl, dass die neueren Versionen von SQL Server plötzlich wie Oracle zu arbeiten begonnen haben (meiner Meinung nach nicht gut). Ich denke, es sollte als Fehler gemeldet werden. Wir sollten die Statistiken in SQL Server nicht manuell aktualisieren müssen.

Select DISTINCT
c.claim_number,
c.claim_number_type,
'SERVICE_ID',
ds.data_source_id
From db1.dbo.std_claim c with (nolock)
Join db2.dbo.source_manager sm with (nolock) on sm.etl_source_id = c.etl_source_id
Join db3.dbo.data_source ds with (nolock) on ds.data_source=c.data_source     
and ds.tenant_id = sm.tenant_id
Where ISNULL(sm.processed_flag,'N') = 'N'
And sm.active_flag = 'Y'
And c.deleted_ind = 'N'
And not exists (Select 1 
From db3.dbo.id_map im
Where im.ID_NAME = 'SERVICE_ID' 
And im.data_source_id = ds.data_source_id
And im.src_id = c.claim_number
And im.src_id_type = c.claim_number_type)
Group By c.claim_number, 
c.claim_number_type, 
ds.data_source_id

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X