2016-08-02 12 views
1

ich unter Abfrage habenSQL Server Optimierung Ausgabe

SELECT DISTINCT ColA,ColB AS S 
    from TableA 
    where ColA <> 0   
    AND CONCAT(ColA,ColB) NOT IN (
            SELECT DISTINCT CONCAT(ColA,ColB) from TableB 
            WHERE ColB <> 0 
           ) 

Tabelle TableA hat über 200000 von Aufzeichnungen und

Tabelle TableB hat über 50000 Aufzeichnungen

Wenn ich diese Abfrage leite es auch nimmt viel Zeit ca. 2 Minuten.

Wie kann ich diese Abfrage optimieren, um die Ausführungszeit zu reduzieren?

Was soll ich tun, um diese Abfrage zu optimieren?

+3

Bitte senden Sie den Ausführungsplan als xml, Tabellenschema mit einigen Beispieldaten – TheGameiswar

+0

Sie haben 2 ANDs in 'ColA <> 0 AND AND CONCAT' – vercelli

+1

Sind Zahlen cols? Sind Sie sicher, dass Sie sie verketten? 'Wählen Sie concat (a, b) von (wählen Sie 11 als a, 2 als b union alle wählen Sie 1, 12) t wo concat (a, b) = '112'' – Serg

Antwort

2

Try this ....

SELECT DISTINCT A.ColA, A.ColB AS S 
from TableA A 
where A.ColA <> 0 
AND NOT EXISTS (SELECT 1 
       from TableB B 
       WHERE B.ColB <> 0 
       AND A.ColA= B.ColA 
       AND A.ColB = B.ColB) 

Hinweis

Ich weiß nicht viel über Ihr Tabellenschema oder Indizes, aber ich weiß sicher eine Sache, dass der Ausdruck CONCAT(ColA,ColB) nicht sargable ist. Schreiben Sie die gleiche Abfrage ein wenig anders und es wird viel schneller, wenn es in Indizes für die Spalten ColA und ColB gibt.

+0

In der Theorie könnte Ihre Abfrage bringen falsche Ergebnisse. In Ihrem Fall wäre 'CONCAT (ColA, ColB)' gleich "CONCAT (ColB, ColA)", oder? –

0

CONCAT wird jeden Index sucht auf Ihre Spalten in beiden Tabellen ausschließen.

Wenn der primäre Zweck Ihrer Abfrage ist, alle ColA, ColB-Kombinationen zu finden, die in TableA und nicht in TableB sind, können Sie etwas wie diese versuchen.

SELECT DISTINCT ColA,ColB AS S 
FROM TableA 
WHERE ColA <> 0 
AND NOT EXISTS(
    SELECT TOP 1 * FROM TableB 
    WHERE TableB.ColA = TableA.ColA 
    AND TableB.ColB = TableA.ColB 
    AND TableB.ColB <> 0 
    ) 

Hinweis: Dies in einem besseren Ausführungsplan als Ihre aktuelle Abfrage aber es ist schwer zu kommentieren, ohne Ihren tatsächlichen Ausführungsplan und bestehende Tabellenstruktur und Indizes

0

Verwendung set operation führen sollen:

SELECT ColA, ColB FROM TableA WHERE ColA <> 0 
EXCEPT 
SELECT ColA, ColB FROM TableB WHERE ColB <> 0 

Nein DISTINCT benötigt Ursache EXCEPT tun dies trotzdem.

0

können Sie mit dieser Abfrage versuchen

SELECT DISTINCT ColA,ColB AS S 
FROM TableA LEFT OUTER JOIN TableB 
    ON TableA.ColA = TableB.ColA 
     and TableA.ColB = TableB.ColB 
WHERE TableA.ColA <> 0 
    and TableB.ColB <> 0 
    and TableB.ColB is null 
0

Da einige Plakate darauf hingewiesen haben, müssen Sie die CONCAT statt der Abfrage auf ColA und ColB unabhängig verwenden, die korrekten Daten zu erhalten.

Wenn dies eine wichtige genug Abfrage ist, um einen eigenen Index zu verdienen, oder CONCAT (ColA, ColB) wird häufig Daten verwendet. Sie könnten eine berechnete Spalte für CONCAT (ColA, ColB) und einen Index für diese berechnete Spalte erstellen.

SELECT DISTINCT 
    A.ColA, A.ColB 
    FROM TableA A 
    LEFT JOIN TableB B 
    ON B.CONCAT(ColA,ColB) = A.CONCAT(ColA,ColB) 
    WHERE A.ColA <> 0 
    and B.ColB <> 0 
    and B.ColB is null 

Ich habe auch Glück Filterung nach unten CTEs verwenden und dann zuletzt alle Berechnungen zu tun, am besten Nutzung der Indizes zu machen, die derzeit auf dem Tisch liegen.

WITH FilteredA as (
    select ColA, ColB 
    from tableA 
    WHERE ColA <> 0), 

    FilteredB as (
    select ColA, ColB 
    from tableB 
    WHERE ColB <> 0) 

    SELECT DISTINCT FilteredA.* 
    from FilteredA 
    LEFT JOIN FilteredB ON FilteredA.ColA = FilteredB.ColB 
    AND FilteredA.ColB = FilteredB.ColB 
    WHERE FilteredA.CONCAT(ColA,ColB) = FilteredB.CONCAT(ColA,ColB)