2017-05-19 3 views
0

Ich habe die komplexe sub-select-Anweisung, die meine Abfrage verlangsamt und auch andere Benutzer blockiert.Wie kann ich die Abfrageleistung verbessern, die andere Benutzer blockiert?

select 

       (Case when (Select COUNT(*) from tblQuoteDetails QD where QD.QuoteGUID = a.QuoteGUID) > 1 then 
           (SELECT Round(Sum(dbo.tblQuoteOptions.Premium),2) 
           FROM dbo.tblQuotes AS Q 
            INNER JOIN dbo.lstQuoteStatus ON Q.QuoteStatusID = dbo.lstQuoteStatus.QuoteStatusID 
            INNER JOIN dbo.tblQuoteOptions ON Q.QuoteGUID = dbo.tblQuoteOptions.QuoteGUID 
            --INNER JOIN dbo.tblQuoteOptionPremiums ON dbo.tblQuoteOptionPremiums.QuoteOptionGuid = dbo.tblQuoteOptions.QuoteOptionGUID 
           WHERE  (Q.ControlNo = a.ControlNo) 
            AND (Q.OriginalQuoteGUID IS NULL) 
            AND (dbo.tblQuoteOptions.Premium <> 0) 
            AND (DATEDIFF(d,ISNULL(null, dbo.GetEffectiveDate(Q.QuoteGUID)), dbo.GetEffectiveDate(Q.QuoteGUID)) <= 0)) 
         Else 
           (SELECT  Round(Avg(dbo.tblQuoteOptions.Premium),2) 
           FROM dbo.tblQuotes AS Q 
            INNER JOIN dbo.lstQuoteStatus ON Q.QuoteStatusID = dbo.lstQuoteStatus.QuoteStatusID 
            INNER JOIN dbo.tblQuoteOptions ON Q.QuoteGUID = dbo.tblQuoteOptions.QuoteGUID 
            --INNER JOIN dbo.tblQuoteOptionPremiums ON dbo.tblQuoteOptionPremiums.QuoteOptionGuid = dbo.tblQuoteOptions.QuoteOptionGUID 
           WHERE  (Q.ControlNo = a.ControlNo) 
            AND (Q.OriginalQuoteGUID IS NULL) 
            AND (dbo.tblQuoteOptions.Premium <> 0) 
            AND (DATEDIFF(d,ISNULL(null, dbo.GetEffectiveDate(Q.QuoteGUID)), dbo.GetEffectiveDate(Q.QuoteGUID)) <= 0)) 
           --GROUP BY dbo.tblQuoteOptions.QuoteOptionID 
         End) As QuotedPremium 
    FROM tblQuotes a 

nicht sicher, ob ich lese richtig Ausführungsplan, aber das ist, was ich sehe: enter image description here

Jede Idee, was Ansatz soll ich hier nehmen?

Dank

+0

meinst du, du kannst [temporäre Tabellen] verwenden (http://stackoverflow.com/questions/16767645/why-is-thetha-a-huge-performance-difference-between-temp-table-and-subselect) ? – luisarcher

+0

Es gibt viele Dinge "links von der Mitte" in dieser Abfrage. Das größte Problem ist die Verwendung von Skalarfunktionen. Sie sind furchtbar ineffizient und du hast sie überall bespritzt. Sie haben völlig sinnlose Funktionen, bei denen der erste Wert null ist. Sie können auch einen Blick auf diesen Artikel werfen. http://sqlblog.com/blogs/aaron_bertrand/archive/2011/09/20/bad-habits-to-kick-using-shorthand-with-date-time-operations.aspx –

+0

Hinweis: Verwenden von GUIDs anstelle von zusammengesetzten Indizes ist eine schreckliche Strategie. Vor allem, wenn Sie gruppierte Indizes auf sie anwenden. MACH DAS NICHT! Es skaliert nicht und wird die Leistung auf Systemen zerstören, auf denen häufig Operationen zum Einfügen, Aktualisieren und Löschen ausgeführt werden. – dbbri

Antwort

1

in die Abfrage der Suche völlig ohne Zugriff auf Ihre Umgebung hat, wird nicht sehr effizient sein, aber ich kann sicher sagen, dass Key Lookups teuer sind, und oft kann man, indem sichergestellt wird, die Spalten beseitigt werden sind aus einer Joined-Tabelle abgerufen werden INCLUEDED in dem verwendeten Index. In Anbetracht der zwei Schlüsselsuchen, die wir zu fast 80% der Abfragekosten machen können, würde ich dort anfangen.

0

Auch ein Teil des Problems ist die Verwendung von DATEDIFF innerhalb einer WHERE-Klausel.

AND (DATEDIFF(d,ISNULL(null, dbo.GetEffectiveDate(Q.QuoteGUID))dbo.GetEffectiveDate(Q.QuoteGUID)) <= 0)) 

Dies wird den Optimierer stark davon abhalten, seinen Job zu erledigen. Die Vereinfachung dieses speziellen Vergleichs könnte einen großen Unterschied machen.

Verwandte Themen