2009-07-15 3 views
0

Unter Refactoring ist meine SQL-Abfrage, die mehr als 10 Minuten dauert und noch läuft ....Hilfe einer SQL-Abfrage

select DISTINCT Auditdata.ID,ns.ProviderMaster_ID as CDRComment 
from Auditdata AuditData 
inner join AuditMaster am 
    on am.ID=AuditData.AuditMaster_ID 
inner join HomeCircleMaster hcm 
    on hcm.Ori_CircleMaster_ID=am.CircleMaster_ID 
    and hcm.Ori_ServiceTypeMaster_ID=1 
    and hcm.Dest_ServiceTypeMaster_ID=1 
inner join NoSeriesMaster ns 
    on (ns.CircleMaster_ID=am.CircleMaster_ID 
    or ns.CircleMaster_ID=hcm.Dest_CircleMaster_ID) 
    and ns.ProviderMaster_ID<>am.ProviderMaster_ID 
    and ns.ServiceTypeMaster_ID=1 
INNER JOIN NoSeriesMaster_Prefix PD 
    ON SUBSTRING(AuditData.CallTo, 1, CONVERT(INT, PD.PrefixLen)) = PD.PrefixNo  
    AND LEN(AuditData.CallTo) = CONVERT(VARCHAR(10), CONVERT(INT, PD.PrefixLen) + CONVERT(INT, PD.AfterPrefixLen)) 
    AND PD.PrefixNo + ns.NoSeries = LEFT(AuditData.CallTo, len(ns.NoSeries) + CONVERT(INT, PD.PrefixLen)) 
where AuditData.TATCallType is null 
    and AuditData.AuditMaster_ID=74 
    and PrefixType='CALL' 

Spalte evey in der Innen verwendet join verwendet, um einen Index und Spalten trotzte in denen Klausel auch definiert Index ...

ist es eine Möglichkeit, über Abfrage zu fasten

Bitte helfen Sie mir ...

Thanx

Liebe Freunde im modifizierten meine SQL-Abfrage ist sein wie folgen noch viel Zeit in Anspruch nehmen Gegen 15000000

modifizierte SQL Query auszuführen sind wie folgt:

select DISTINCT Auditdata.ID,ns.ProviderMaster_ID as CDRComment from Auditdata AuditData inner join AuditMaster am on am.ID=AuditData.AuditMaster_ID inner join HomeCircleMaster hcm on hcm.Ori_CircleMaster_ID=am.CircleMaster_ID and hcm.Ori_ServiceTypeMaster_ID=1 and hcm.Dest_ServiceTypeMaster_ID=1 inner join NoSeriesMaster ns on (ns.CircleMaster_ID=am.CircleMaster_ID or ns.CircleMaster_ID=hcm.Dest_CircleMaster_ID) and ns.ProviderMaster_ID<>am.ProviderMaster_ID and ns.ServiceTypeMaster_ID=1 INNER JOIN NoSeriesMaster_Prefix PD ON Auditdata.callto like PD.PrefixNo + '%' AND AuditData.CallTolen = PD.PrefixLen + PD.AfterPrefixLen AND PD.PrefixNo + ns.NoSeries = LEFT(AuditData.CallTo, NoSeriesLen + PD.PrefixLen) 
where AuditData.TATCallType is null and AuditData.AuditMaster_ID=74 and PrefixType='CALL' 

Nun, was kann ich tun? ?

Lieber Freund

meine Abfrage nimmt viel Zeit, weil unten Teil des Codes NoSeriesMaster enthalten 4000 Zeilen und Auditdata 15000000 Reihen mit inneren Verknüpfung jedes callto Spalten Datensatz in Auditdata mit dem Noseriesmaster abgestimmt

INNER JOIN NoSeriesMaster_Prefix PD
AUF SUBSTRING (AuditData.CallTo, 1, KONVERT (INT, PD.PrefixLen)) = PD.PrefixNo
UND LEN (AuditData.CallTo) = C ONVERT (VARCHAR (10), KONVERTIEREN (INT, PD.PrefixLen) + CONVERT (INT, PD.AfterPrefixLen))
UND PD.PrefixNo + ns.NoSeries = LINKS (AuditData.CallTo, len (ns.NoSeries) + CONVERT (INT, PD.PrefixLen))
wo AuditData.TATCallType null ist und AuditData.AuditMaster_ID = 74 und PrefixType = 'CALL'

+0

Lieber Freund, Wenn ich unter 2 Abfrage ausgeführt ist sowohl die Ausführungszeit verschiedene ... select id von Auditdata wo substring (callto, 1,2) '91' = und len (callto) = 12 \t (Diese Abfrage ausführen, in 25 Sekunden) select-ID von Auditdata wo callto wie '91%‘und calltolen = 12 (diese Abfrage ausführen in 33 Sekunden) \t y diese verschiedenen Funktionen in – John

Antwort

3

es ist schwer zu sagen, was es verursacht, aber die folgenden beitragen:

  • Das Ausführen von Transformationen wie SUBSTRING, CONVERT, LEFT usw. auf Werten in Joins ruiniert die Leistung, weil es SQL Server bedeutet c a't nutzt seine Indizes effektiv. Möglicherweise möchten Sie die Spalten, die Sie für diese Art der Konvertierung benötigen, in separate Spalten extrahieren und indizieren.

  • Suboptimale Indizes - abgesehen von denen, die Sie aufgrund der Conversions nicht verwenden können, sind die anderen Spalten, auf die Sie beitreten, korrekt indiziert? Sehen Sie sich den Index-Tuning-Assistenten an, der Ihnen vielleicht hier helfen kann.

  • +0

    WHERE-Klausel (oder verbinden) - sein diese das zerstört die Leistung. Jede Berechnung muss in jeder Zeile mehrmals durchgeführt werden - dies kann nur schneller gemacht werden, indem abgeleitete Spalten erstellt und indexiert werden. – cjk

    +1

    @ck - Ist das nicht das, was ich gesagt habe? –

    +0

    ok im Erstellen von abgeleiteten Spalten und dann überprüfen – John

    2

    Sie können die Ausführungsplanansicht in SQL Server Management Studio verwenden, wenn Sie diese Abfrage ausführen. Es zeigt Ihnen, in welchen Schritten SQL die meiste Zeit für die Verarbeitung Ihrer Abfrage benötigt. Von dort haben Sie zumindest eine Idee, wo die Optimierung stattfinden muss.

    Der Ausführungsplan ist auch in SQL Server Management Studio Express fyi enthalten.

    Öffnen Sie einfach ein neues Abfragefenster, klicken Sie auf Abfrage> Geschätzten Ausführungsplan anzeigen und führen Sie Ihre Abfrage aus. Der Ausführungsplan wird angezeigt, sobald die Abfrage abgeschlossen ist.

    +0

    im SQL Server 2000 verwenden – John

    +0

    Query Analyzer hat auch einen Ausführungsplan, ich habe es nicht installiert jetzt, so kann ich Ihnen nicht genau sagen, wo es zu finden, aber es ist definitiv dort drin ! – Peter

    0

    Und noch etwas - Sie können versuchen, einige Bedingungen Ort, von wo in JOIN:

    from Auditdata AuditData 
    inner join AuditMaster am 
        on am.ID=AuditData.AuditMaster_ID AND AuditData.TATCallType is null 
        and AuditData.AuditMaster_ID=74 
    

    aber ich denke, Query-Optimizer sollte es tun.

    Wie auch immer, Sie müssen den Ausführungsplan zuerst anzeigen.

    0

    Der Ausführungsplan würde Ihnen genau sagen, was die meiste Zeit kostet.

    Es ist wahrscheinlich der letzte Join, der am meisten Arbeit verursacht. Wenn Sie berechnete Werte vergleichen, kann die Datenbank keine Indizes für die Suche verwenden.

    Ich sehe, dass Sie eine CONVERT(VARCHAR(10), ...) auf einen numerischen Wert, aber dann vergleichen Sie es mit einer Zahl. Sie sollten diese Konvertierung einfach entfernen können.

    Sie konvertieren das Feld PrefixLen in eine Zahl an mehreren Stellen. Ist dieses Feld wirklich ein Textfeld, und wenn ja, können Sie es in ein numerisches Feld umwandeln?

    Sie vergleichen den ersten Teil von AuditData mit PrefixNo, dann vergleichen Sie ein bisschen mehr des Feldes mit PrefixNo + NoSeries. Wenn es kein Problem mit Werten "bluten" gibt, weil ein Trennzeichen fehlt (z. B. '01' + '23' = '0' + '123'), können Sie einfach den ersten Vergleich entfernen.