2017-07-09 4 views
0

Ich habe die folgende gespeicherte Prozedur, die gegen eine ExtractedMessages-Tabelle ausgeführt wird, die bis zu 100M Datensätze enthalten kann (100.000.000).Gespeicherte SQL Server-Prozedur-Optimierung

Für die Zwecke meiner Anwendung sollte diese gespeicherte Prozedur in laufen weniger als einer Sekunde

CREATE PROCEDURE GetNextMessages 
    @taskId bigint 
AS 
BEGIN 
    SET NOCOUNT ON; 

    DECLARE @ci INT 
    DECLARE @cr INT 

    SELECT 
     @ci = CurrentIndex, @cr = CurrentResources 
    FROM 
     ExtractedTasks 
    WHERE 
     Id = @taskId 

    UPDATE ExtractedTasks 
    SET CurrentIndex = @ci + @cr 
    WHERE Id = @taskId 

    SELECT * 
    FROM ExtractedMessages 
    WHERE TaskId = @taskId 
    ORDER BY Id 
     OFFSET @ci ROWS 
     FETCH NEXT @cr ROWS ONLY 
END 

NB: cr nicht mehr als 1500

+0

beachten Sie, dass Tabelle _ExtractedMessages_ ist bereits indiziert auf _Id_ und auf _TaskId_ –

+0

Sie haben seltsame Paginierungslogik. –

+0

Brauchen Sie wirklich alle Spalten im Ergebnis? Wenn nein, dann entfernen Sie das '*' und fügen Sie nur die erforderlichen Spalten –

Antwort

0

Danke Jeder für Ihre freundliche Hilfe Ich war in der Lage, das Problem zu identifizieren, schließlich war es ein Speicherverwaltungsproblem auf dem Server, auf dem SQL Server ausgeführt wird. Ich habe den dedizierten Speicher des Servers erhöht. Und das Problem wurde behoben. Der SP funktioniert jetzt reibungslos

0

Statt zweimal abzufragen Tisch sein kann man tun könnte die folgenden:

DECLARE @ci INT 
DECLARE @cr INT 

DECLARE @T TABLE (
    ci INT 
    , cr INT 
    ); 

UPDATE ExtractedTasks 
SET CurrentIndex = CurrentIndex + CurrentResources 
OUTPUT DELETED.CurrentIndex, DELETED.CurrentResources 
INTO @T (ci, cr) 
WHERE Id = @taskId; 

SELECT 
    @ci = ci, @cr = cr 
FROM 
    @T 

SELECT * 
FROM ExtractedMessages 
WHERE TaskId = @taskId 
ORDER BY Id 
    OFFSET @ci ROWS 
    FETCH NEXT @cr ROWS ONLY 

Der Schlüssel hier ist OUTPUT-Klausel. Es wird gelöschte Datensätze (Voraktualisierungswerte) in eine Tabellenvariable einfügen. Das bedeutet, dass Sie mehrere Auswahlvorgänge aus einer Tabelle durch eine ersetzen. Anders als richtige Indizes sehe ich nichts für Verbesserungen.

Stellen Sie außerdem sicher, dass Sie nur die Spalten auswählen, die Sie benötigen, nicht alles. In der Regel empfiehlt es sich, genau die Spalten aufzulisten, die Sie benötigen.

+0

+1 Aber jetzt, wo ich das Problem reproduzieren könnte, eine einfache Zählung (*) auf dem Tisch dauert 6 Sekunden –

+0

Ausführungspläne beifügen, sonst nicht viel können wir helfen. –