2016-06-28 11 views
1

Ich habe an einer alten überwachten gespeicherten Prozedur gearbeitet, die langsam ausgeführt wird. Ich habe einige Erfolge beim Anwenden der Indizierung und der Sargable-Abfrage der Abfrage erzielt.SQL-Leistung langsam (Verbessert Einfügen in Temp-Tabelle)

Die gespeicherte Prozedur dauert jedoch immer noch über eine Minute. Ich denke, das Problem liegt in der Temp-Tabelle einfügen. Ich habe versucht, einen Index zu der temporären Tabelle anzuwenden, aber dies wird nur die Leistung reduzieren, wie:

Die Anzahl der Indizes auf einer Tabelle der dominierende Faktor für Einfügeleistung ist. Je mehr Indizes eine Tabelle hat, desto langsamer wird die Ausführung. Die INSERT-Anweisung ist die einzige Operation, die nicht direkt von der Indexierung profitieren kann, da sie eine Nirgendwo-Klausel enthält.

SQL-Code

Ich habe unter dem Code-Schnipsel aus dem Audit-Verfahren veröffentlicht, der die längste Zeit nimmt den Ausführungsplan zu verarbeiten und zu enthalten.

SELECT dbo.[Audit Result Entry Detail].PK_ID, 
    dbo.[Audit Result Entry Detail]....... 
    45-50 other columns selected from Audit Result Entry Detail 
    (Note i need to select all these) 
    dbo.[Audit Register].Audit_Date, 
    dbo.[Audit Register].Audit_Type, 
    dbo.[Audit Register].ContextUser 
INTO #temp5 

FROM dbo.[Audit Result Entry Detail] 
    INNER 
    JOIN dbo.[Audit Register] 
    ON dbo.[Audit Result Entry Detail].FK_RegisterID = dbo.[Audit Register].PK_ID 
    INNER 
    JOIN (
    SELECT MAX(Audit_Date) AS DATE, 
     FK_RegisterID 
     FROM dbo.[Audit Result Entry Detail] 
     INNER 
     JOIN dbo.[Audit Register] 
     ON dbo.[Audit Result Entry Detail].FK_RegisterID = dbo.[Audit Register].PK_ID 
    WHERE Audit_Date >= @StartDate AND Audit_Date < DATEADD(dd,1,@EndDate) 
      --WHERE ((SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, Audit_Date))) >= @StartDate 
      -- AND (SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, Audit_Date))) <= @EndDate) 
       AND part_number = @ParticipantNumber 
     GROUP 
     BY FK_RegisterID 
    ) dt 
    ON dbo.[Audit Result Entry Detail].FK_RegisterID = dt.FK_RegisterID 
    AND dbo.[Audit Register].Audit_Date = dt.[date] 
    WHERE part_number = @ParticipantNumber 

Ausführungsplan: Execution_Plan

Ich glaube, der Engpass der Tabelle # Temp5 ist, meine Frage ist, ihr eine Art, wie ich in die temporäre Tabelle den Einsatz beschleunigen kann, oder gibt es eine bessere Alternative zu einer temporären Tabelle?

Danke für Ihre Hilfe.

+0

Bitte geben Sie den Link zum Ausführungsplan statt als Bild – TheGameiswar

+0

Leistungsfragen sollten "EXPLAIN ANALYSE" und einige Informationen über Tabellengröße, Index, aktuelle Zeit Leistung, Wunschzeit usw. enthalten. Langsam ist ein relativer Begriff und wir brauchen ein echter Wert zum Vergleichen. –

+0

Ausführungsplan zeigt das Einfügen von Daten in temporäre Tabelle dauert 41% der Gesamtzeit. Also dachte ich, es fügt eine große Anzahl von Zeilen in die temporäre Tabelle ein, aber es sieht so aus, als hätte das Endergebnis nur 3462 Zeilen. Kann mir das jemand erklären? Vielen Dank – FLICKER

Antwort

3

Ich denke, es könnte einige verschiedene Ursachen für das Problem geben. Zumindest ist die Annahme, dass aufgrund der großen Anzahl von Feldern in einem Datensatz kann einen Seitenüberlauf in Temp Heap-Tabelle verursachen. Außerdem könnte es zu Konflikten in Tempdb oder sogar zu Langsamkeit kommen. Die allgemeinen Vorschläge könnten also lauten:
1. Versuchen Sie, wie bereits vorgeschlagen, keine temporäre Tabelle zu verwenden.
2. Versuchen Sie nach Möglichkeit, die Datensatzgröße auf eine Seite zu beschränken. Oder noch besser, wenn Sie 2-3 Datensätze in eine Seite passen.
3. Wenn es möglich ist, verwenden Sie "staging" -Tabelle mit Clustered-Index anstelle der temporären Tabelle. Die Tabelle nicht abschneiden, nur löschen.
4. Wenn Sie temporäre Tabelle verwenden: Erstellen Sie Tabelle vor dem Einfügen mit gruppiertem Index darauf.
5. Fallow Paul Randal Vorschläge über TempDB: http://www.sqlskills.com/blogs/paul/the-accidental-dba-day-27-of-30-troubleshooting-tempdb-contention/

Für tiefere Fehlersuche, würde ich vorschlagen, die während der Ausführung der Abfrage, zu erfassen wartet, Schlösser, I/O, Speicher und CPU-Aktivität.

+1

Vielen Dank für Ihre Hilfe, indem Sie Punkt 4 aus Ihrer Antwort verwenden Ich habe den Speichervorgang jetzt in etwa 15 Sekunden ausgeführt. Mit ein paar weiteren Anpassungen glaube ich, dass ich es noch schneller laufen lassen kann. –

+0

In Punkt 1 haben Sie vorgeschlagen, keine temporäre Tabelle zu verwenden, aber was würden Sie anstelle einer temporären Tabelle vorschlagen? Ich habe Tabellenvariablen, CTEs und abgeleitete Tabellen betrachtet. Die Tempentabelle erweist sich jedoch als bessere Lösung. –

+0

Siehe # 3. Eine "Staging" -Tabelle. Das ist keine Silver Bullet, aber in bestimmten Fällen könnte es helfen. Ich kann nicht wirklich sagen, ob es dein Fall ist oder nicht. Sie wissen besser wo Ihre Behauptung ist und Sie können es versuchen. –