2010-12-01 2 views
1

wenn ich diese Abfrage ausführenUnexpected geschätzte Zeilen in Abfrageausführungsplan (SQL Server 2000)

select user from largetable where largetable.user = 1155 

(beachten Sie, ich bin Benutzer Abfrage nur dies zu seinem einfachstenen Fall zu reduzieren)

Und schauen der Ausführungsplan, um einen Index suchen ist geplant [Largetable einen Index für Benutzer hat], und die geschätzten Zeilen ist die korrekte 29.

Aber wenn ich

select user from largetable where largetable.user = (select user from users where externalid = 100) 

[mit dem Ergebnis der Unterabfrage wie oben der einzelne Wert 1155 nur zu sein, wenn ich es schwer code]

Die Abfrageoptimierer 117.000 Zeilen im Ergebnis schätzt. Es gibt ungefähr 6.000.000 Zeilen in der Tabelle "Groß", 1700 Zeilen in den Benutzern. Wenn ich die Abfrage natürlich durchführe, bekomme ich trotz der riesigen geschätzten Zeilen die richtigen 29 Zeilen zurück.

Ich habe Statistiken mit Fullscan auf beiden Tabellen über die relevanten Indizes aktualisiert, und wenn ich mir die Statistiken ansehe, scheinen sie korrekt zu sein.

Für einen bestimmten Benutzer gibt es nicht mehr als 3.000 Zeilen in Großtabelle.

Warum sollte der geschätzte Ausführungsplan eine so große Anzahl von geschätzten Zeilen anzeigen? Sollte der Optimierer basierend auf den Statistiken nicht wissen, dass er nach einem Ergebnis sucht, das 29 entsprechende Zeilen oder MAXIMAL 3.000 Zeilen aufweist, selbst wenn er den Benutzer nicht kennt, der von der Unterabfrage ausgewählt wird? Warum diese riesige Schätzung? Das Problem ist, dass diese große Schätzung dann eine andere Verknüpfung in einer größeren Abfrage beeinflusst, um eine Suche statt einer Suche durchzuführen. Wenn ich die größere Abfrage mit der Unterabfrage ausführe, dauert es 1 Minute 40 Sekunden. Wenn es mit der 1155 hardcodiert ausgeführt wird, dauert es 2 Sekunden. Das ist sehr ungewöhnlich für mich ...

Danke,

Chris

Antwort

0

Haben Sie dies versuchen?

SELECT lt.user 
FROM Users u 
    INNER JOIN largeTable lt 
     ON u.User = lt.User 
WHERE u.externalId = 100 

Bitte sehen: subqueries-vs-joins

+1

Ja, und das Umschreiben als Beitritt hat das gleiche Problem! – Querylous

1

Der Optimierer tut das gut es kann, aber Statistiken und Zeilenanzahl Schätzungen nur so weit gehen (wie Sie sehen).

Ich nehme an, dass Ihre komplexere Abfrage nicht einfach als eine Verknüpfung ohne Unterabfrage umgeschrieben werden kann. Wenn es sein kann, sollten Sie das zuerst versuchen.

Andernfalls ist es Zeit für Sie, Ihr zusätzliches Wissen über die Art Ihrer Daten zu verwenden, um den Optimierer mit hints zu helfen. Schauen Sie sich speziell die forceseek Option in den index Hinweise an. Beachten Sie, dass dies schlecht sein kann, wenn sich Ihre Daten später ändern.

+0

'forceseek' ist nur 2008. Das OP ist auf 2000. –

+0

Ah, habe das nicht bemerkt. Seit einiger Zeit vor 2000 migriert, hatte ich nichts, um es zu testen. :( – Donnie

+0

Dank Donnie; Ich bekomme den gleichen Effekt, wenn ich als Beitritt neu schreiben. Ich glaube nicht, SS 2000 hat die forceseek, aber ich werde auf das .. – Querylous