Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Paginierung in SQL – Leistungsproblem

Ich überprüfe immer, auf wie viele Daten ich in Abfragen zugreife, und versuche unnötige Spalten und Zeilen zu eliminieren Die langsame Leistung der Abfrage kann daran liegen, dass Sie „Select *“ ausführen. Wenn Sie alle Spalten aus der Tabelle auswählen, erhalten Sie keinen guten Ausführungsplan. Überprüfen Sie, ob Sie nur ausgewählte Spalten benötigen, und stellen Sie sicher, dass Sie den korrekten abdeckenden Index für die Tabellenaufträge haben.

Da die explizite SKIPP- oder OFFSET-Funktion in der SQL 2008-Version nicht verfügbar ist, müssen wir eine erstellen, die wir durch INNER JOIN erstellen können. In einer Abfrage generieren wir zuerst eine ID mit OrderDate und nichts anderes wird in dieser Abfrage enthalten sein. Wir tun dasselbe in der zweiten Abfrage, aber hier wählen wir auch einige andere interessante Spalten aus der Tabelle ORDER oder ALL aus, wenn Sie ALLE Spalten benötigen. Dann VERBINDEN wir dies, um die Ergebnisse nach ID und OrderDate abzufragen, und HINZUFÜGEN SKIPP-Zeilenfilter für die erste Abfrage, bei der der Datensatz seine minimale Größe hat was erforderlich ist. Probieren Sie diesen Code aus.

    SELECT q2.*
    FROM
    (
        SELECT ROW_NUMBER() OVER ( ORDER BY OrderDate ) AS RowNum, OrderDate
        FROM      Orders
        WHERE     OrderDate >= '1980-01-01'
    )q1
    INNER JOIN 
    (
        SELECT ROW_NUMBER() OVER ( ORDER BY OrderDate ) AS RowNum, *
        FROM      Orders
        WHERE     OrderDate >= '1980-01-01'
    )q2
        ON q1.RowNum=q2.RowNum AND q1.OrderDate=q2.OrderDate AND q1.rownum BETWEEN 30000 AND 30020
    IF object_id('TestSelect','u') IS NOT NULL
        DROP TABLE TestSelect
    GO
    CREATE TABLE TestSelect
    (
        OrderDate   DATETIME2(2)
    )
    GO

    DECLARE @i bigint=1, @dt DATETIME2(2)='01/01/1700'
    WHILE @I<=2000000
    BEGIN

        IF @i%15 = 0
            SELECT @DT = DATEADD(DAY,1,@dt)

        INSERT INTO dbo.TestSelect( OrderDate )
        SELECT @dt

        SELECT @[email protected]+1
    END
    SELECT q2.*
    FROM
    (
        SELECT  ROW_NUMBER() OVER ( ORDER BY OrderDate ) AS RowNum 
                ,OrderDate
        FROM TestSelect
        WHERE OrderDate >= '1700-01-01'
    )q1
    INNER JOIN
    (
        SELECT  ROW_NUMBER() OVER ( ORDER BY OrderDate ) AS RowNum 
                ,*
        FROM TestSelect
        WHERE OrderDate >= '1700-01-01'
    )q2
        ON q1.RowNum=q2.RowNum 
        AND q1.OrderDate=q2.OrderDate 
        AND q1.RowNum BETWEEN 50000 AND 50010