2016-04-20 8 views
0

Ich habe eine Ansicht mit zwei separaten Abfragen mit einer Union alle. Zum Beispiel:So optimieren Sie die Ansicht mit Union Alle

CREATE VIEW MyView AS 

SELECT foo.id, bar.data 
FROM foo 
INNER JOIN bar ON foo.id = bar.id 

UNION ALL 

SELECT baz.id, baz.data 
FROM baz 

ich dann eine select-Anweisung für die Ansicht wie folgt ausführen:

SELECT * FROM MyView WHERE id = 1 

Die ID von 1 existiert nur in der ersten select-Anweisung. Die mit den foo und bar Tabellen, aber die Union mit der baz Tabelle verursacht immer noch, dass es langsamer läuft. Es ist schneller, wenn Sie die Verbindung beenden. Ich muss es jedoch dort lassen, da manchmal eine ID verwendet wird, die Ergebnisse von der zweiten Select-Anweisung zurückgibt.

Meine Frage ist: Gibt es eine Möglichkeit, sql Server zu helfen wissen, dass es keine Ergebnisse im zweiten Teil der Union alle gibt, so dass es diese Abfrage nicht ausführen muss?

Alle diese Daten befanden sich in einer Tabelle. Dies ist eine neue Datenstruktur, und alle unsere älteren Anwendungen stützen sich auf diese Ansicht, um Daten aus dieser neuen Datenstruktur zu lesen. Aus diesem Grund wissen wir nicht, welche Tabelle die Ergebnisse im Voraus haben wird.

+0

Wenn Sie wissen vorher die Zeile Sie suchen aus der ersten Tabelle, Abfrage, die direkt – Amit

+0

BTW, wenn Sie echte Abfrage sind ähnlich dies beinhaltet nicht einmal 'foo', benutze' bar' direkt, es hat alle Daten, die du brauchst. – Amit

+0

Nein, das ist nur ein Beispiel. In Wirklichkeit gibt es Felder, die wir von beiden Tabellen benötigen. Ich habe einen Schnitt gemacht, der erklärt, warum ich vorher nicht weiß, welcher Tisch die Ergebnisse haben wird, die wir brauchen. – rgvassar

Antwort

0

Es gibt eine Möglichkeit, eine bedingte Union Join zu machen. Versuchen Sie zu sehen, ob es die Abfrage beschleunigt, indem Sie den Ausführungsplan nachschlagen. Vielleicht ist dein Flaschenhals nicht genau da, wo du denkst?

Sproc mit einem Parameter könnte Trick anstelle einer Ansicht tun, wenn Sie keine Bearbeitung vornehmen werden.

CREATE PROCEDURE procName 
-- Add the parameters for the stored procedure here 
@id INT = 1 
AS 
BEGIN 
SET NOCOUNT ON; 

SELECT foo.id, bar.data 
FROM foo 
INNER JOIN bar ON foo.id = bar.id 

UNION ALL 

SELECT baz.id, baz.data 
FROM baz 
WHERE baz.id = @id 
END 
GO 

Wenn Sie unbedingt einen Blick wie Tabelle benötigt, um eine gespeicherte Funktion in der folgenden Art von Format implementieren:

CREATE FUNCTION v_emp (@pintEno INT) 
RETURNS TABLE 
AS 
RETURN 
    SELECT * FROM emp WHERE [email protected]; 
This allows you to use it as a normal view, with: 
--Query it like : 
SELECT * FROM v_emp(10) 
+0

Alle Ihre Lösungen würden erfordern, dass ich jede Anwendung neu schreibe, die auf diese Ansicht zugreift, um im Grunde keine Ansicht zu verwenden. Das kann ich jetzt nicht tun. Ich bin auf der Suche nach einer Möglichkeit, die Ansicht zu optimieren und die gleichen Ergebnisse wie bisher zu erhalten. – rgvassar

+0

Was ist das Ergebnis Ihres Ausführungsplans? Die Funktion create kann Ihre Ansicht komplett ersetzen, wenn Sie es gleich nennen. – WickedFan

+0

Auch .. siehe HAVING-Klausel. SELECT * FROM MyView MIT id = 1 Ausführung Vergleichen plant – WickedFan

-1

Haben Sie einen Index für baz(id)? Ich würde erwarten, ein Index für diese Abfrage verwendet werden:

SELECT foo.id, bar.data 
FROM foo 
INNER JOIN bar ON foo.id = bar.id 
UNION ALL 
SELECT baz.id, baz.data 
FROM baz 
WHERE baz.id; 
+0

Ja, es ist der Primärschlüssel, so dass es ein Clustered-Index auf sich. Es hat jedoch etwa 16 Millionen Datensätze, so verlangsamt es die Abfrage noch ein wenig. Ich hatte gehofft, dass es einen Weg gab, um zu erkennen, dass dieser Teil der Abfrage überhaupt nicht ausgeführt werden musste. – rgvassar

+0

Dies ist identisch mit dem oben Gesagten. Siehe SQL in sproc eingebettet. – WickedFan

+0

@ rgvassar. . . Wie verlangsamt es die Abfrage?Einen Datensatz in einem Primärschlüsselindex nachzuschlagen und ihn nicht zu finden, sollte sehr wenig Zeit in Anspruch nehmen. Welchen Unterschied in der Leistung sehen Sie? –