2010-11-30 12 views
2

Ich versuche, die Geschwindigkeit einer Abfrage zu optimieren, die einen redundanten Abfrageblock verwendet. Ich versuche, eine Reihe weise SQL Server 2008 mit der Abfrage unten beizutreten.Zurücksetzen der ausgewählten Unterabfrage/Ergebnis

Select * from 
(<complex subquery>) cq 
join table1 t1 on (cq.id=t1.id) 
union 
Select * from 
<complex subquery> cq 
join table2 t2 on (cq.id=t2.id) 

Die <complex subquery> ist genau das gleiche auf beiden Gewerkschafts Sub-Abfrage Stücke außer wir es mit mehreren verschiedenen Tabellen verknüpfen müssen die gleichen Spaltendaten zu erhalten.

Gibt es eine Möglichkeit, die Abfrage entweder neu schreiben, um es schneller zu machen, ohne eine temporäre Tabelle zum Zwischenspeichern von Ergebnissen zu verwenden?

+2

CTE ist vielleicht? Google dafür und sehen Sie, ob es Ihren Bedürfnissen entspricht. – leppie

+1

@leppie - CTEs werden die Ergebnisse im Allgemeinen nicht ohne die Verwendung eines Planführers, wie hier beschrieben, materialisieren http://explainextended.com/2009/05/28/generating-xml-in-subqueries/ –

Antwort

3

Warum nicht eine temporäre Tabelle verwenden und sehen, ob das die Ausführungsstatistik verbessert?

Unter bestimmten Umständen fügt der Abfrageoptimierer dem Plan, der Unterabfragen zwischenspeichert, automatisch eine Spooldatei hinzu, obwohl dies im Grunde nur eine temporäre Tabelle ist.

Haben Sie Ihren aktuellen Plan überprüft, um sicherzustellen, dass die Abfrage tatsächlich mehr als einmal ausgewertet wird?

+0

Temp-Tabelle ist der Weg zu gehen, obwohl Sie möglicherweise sicherstellen müssen, dass Sie Ihre tempdb nicht abstürzen und den Rest Ihrer Datenbank verlangsamen. –

+0

Die oben erwähnte Abfrage wird in einem Suchfeld verwendet, was bedeutet, dass bei der aktuellen Benutzerlast diese Abfrage irgendwo zwischen 100 bis 1000 Mal pro Sekunde ausgelöst wird ... Denken Sie, dass tempDb das verarbeiten kann? – Mulki

1

Ohne ein konkretes Beispiel zu helfen, es ist schwierig, aber versuchen Sie eine WITH-Anweisung, so etwas wie:

WITH csq(x,y,z) AS (
    <complex subquery> 
) 
Select * from 
csq 
join table1 t1 on (cq.id=t1.id) 
union 
Select * from 
csq 
join table2 t2 on (cq.id=t2.id) 

es manchmal Dinge kein Ende

0

Ist die Art der Abfrage ermöglicht es Ihnen, beschleunigt zu invertieren es? Anstatt "(Join, Join) Union", "(Union) Join"? Wie:

Select * from 
(<complex subquery>) cq 
join (
    Select * from table1 t1 
    union 
    Select * from table2 t2 
) ts 
on cq.id=ts.id 

bin ich nicht wirklich sicher, ob doppelte Auswertung Ihrer komplexen Abfrage ist eigentlich das, was falsch ist. Aber nach Ihrer Frage wäre dies eine Form der Abfrage, die SQL dazu ermutigen würde, nur <complex query> einmal auszuwerten.

+0

Leider nicht ... die Ergebnisse der komplexen Abfrage ist in den beiden sql Union Snippets erforderlich .... und ja im Versuch, mehrere Auswertung komplexer Unterabfrage zu vermeiden – Mulki