Warum setzen einer WHERE-Klausel Blick von außen haben schreckliche Leistung
Lassen Sie uns sagen, Sie haben einen Blick:
CREATE VIEW dbo.v_SomeJoinedTables AS
SELECT
a.date,
a.Col1,
b.Col2,
DENSE_RANK()
OVER(PARTITION BY a.date, a.Col2 ORDER BY a.Col3) as Something
FROM a JOIN b on a.date = b.date
Habe ich gefunden, dass die Leistung:
SELECT *
FROM v_SomeJoinedTables
WHERE date > '2011-01-01'
ist viel schlimmer, als
SELECT *,
DENSE_RANK()
OVER(PARTITION BY a.date, a.Col2 ORDER BY a.Col3) as Something
FROM a JOIN b ON a.date = b.date
WHERE a.date > '2011-01-01'
Ich bin sehr überrascht, dass der Abfrageplan für diese beiden Aussagen sind nicht gleich.
Habe ich auch versucht, mit Hilfe einer inline-Tabellenwertfunktion, aber die Abfrage dauert noch 100-1000 mal länger als der code, wo ich kopieren und fügen Sie den view-Logik.
Irgendwelche Ideen?
- Naja was die query-Pläne Aussehen? Fehlt ein index? Ist der Ansicht, Rücksendung zu viele Zeilen? Wenn die where-Klausel wird angewendet an der falschen Stelle?
- Sieht dein Blick zufällig den Aufruf einer Ansicht?
- Was passiert, wenn Ihre Ansicht nicht enthalten, eine windowing-Funktion? Was ist das erwartete semantische Ergebnis einer VIEW berechnet, dass Rang über den gesamten Satz, sondern eine Abfrage auf die view fügt eine neue Bedingung-sollte der RANG insde angewendet werden, bevor oder nachdem die Bedingung außerhalb?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Es heißt "Prädikat schieben" aka latente filtern.
SQL Server nicht immer realisieren, WO können Sie angewendet werden "weiter oben" in der Ansicht effektiv.
Es wurde entschärft, die in SQL Server 2008 arbeiten mehr als erwartet
Ich bin kein SQL-Experte, also ich kann mich gewählt für meine Dummheit, aber meine Vermutung ist, dass im ersten Fall SQL ist das abrufen der Ergebnisse der gesamte Ansicht vor der Anwendung des Prädikat in der WHERE-Klausel. Also, wenn Sie die Abfrage anzeigen, es wählt alle Datensätze, legt diese im Speicher, und dann gilt das Datum filter, nachdem es fertig ist.
Scheint dies ähnlich zu der Art und Weise der gesamte Datensatz angegebenen Verknüpfungen abgerufen wird, die vor der Anwendung der filter in der WHERE - (Lektion hier ist, dass Sie gelten sollen Prädikate in Ihrer ON-Klausel, wenn möglich).
Es sei denn, die Ansichten sind unterschiedlich behandelt, irgendwie.
der OVER () - syntax war ganz neu im SS2005 und anscheinend nicht gut integriert in die Optimierung. Ich schlage vor, Sie versuchen eine eher traditionelle Ausdruck? Wohl KEIN Ausdruck, wenn Sie sich über optimizability.
http://www.sqlteam.com/article/sql-sever-2005-using-over-with-aggregate-functions
Oder, besser, ein bisschen mehr vertraut mit den profiler - Sicht sollte reparierbar.
Technisch, du bist nicht der Vergleich zwischen den gleichen SQL-Anweisungen. Ihr Blick zeigt, dass es gibt
a.date, a.Col1, b.Col2,
plus Ihre DENSE_RANK () - Funktion. In der Abfrage, ohne die Aussicht, Sie alle Spalten zurückzugeben.Auf den ersten, können Sie denken, dass wieder alle Spalten wäre noch schlimmer. Aber es ist schwierig zu bestimmen, welche wäre besser, ohne zu wissen, was die Struktur der Tabelle, einschließlich Indizes, aussieht.
Haben Sie im Vergleich der Abfragepläne für jede Anweisung?
Als work-around würde ich vorschlagen, mit einer Funktion anstelle einer Ansicht, so dass Sie pass in parameter data.