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

Serverseitiges Paging in SQL Server

Der CTE nicht (notwendigerweise) "aktualisiert". Es ist nicht so, dass es zwangsläufig alle Zeilen an einen anderen Ort kopieren und andere Operationen über die Kopie ausführen wird (obwohl es sich so verhalten kann, dass der Optimierer entscheidet, dass es besser ist).

Nehmen wir diese einfache Abfrage:

SELECT  *
FROM    (
        SELECT  *,
                ROW_NUMBER() OVER (ORDER BY id) rn
        FROM    mytable
        ) q
WHERE   rn BETWEEN 101 AND 110

und schauen Sie sich den Plan an, dann sehen wir so etwas:

  |--Filter(WHERE:([Expr1003]>=(101) AND [Expr1003]<=(110)))
       |--Top(TOP EXPRESSION:(CASE WHEN (110) IS NULL OR (110)<(0) THEN (0) ELSE (110) END))
            |--Sequence Project(DEFINE:([Expr1003]=row_number))
                 |--Segment
                      |--Clustered Index Scan(OBJECT:([ee].[dbo].[mytable].[PK__mytable__3213E83F29C2D227]), ORDERED FORWARD)

Hier werden die Datensätze gescannt (in id Reihenfolge, da die Tabelle auf id geclustert ist ), der ROW_NUMBER zugewiesen wurde (Dies ist, was Sequence Project tut) und an TOP weitergeleitet die die Ausführung einfach anhält, wenn ein bestimmter Schwellenwert erreicht ist (110 Aufzeichnungen in unserem Fall).

Diese 110 Datensätze werden an Filter übergeben der die Datensätze nur mit rn weitergibt größer als 100.

Die Abfrage selbst scannt nur 110 Aufzeichnungen:

SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 1 ms.

(строк обработано: 10)
Table 'mytable'. Scan count 1, logical reads 3, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 0 ms.

auf 3 Seiten.

Sehen wir uns nun die nicht paginierte Abfrage an:

SELECT  *
FROM    mytable
ORDER BY
        id

Das ist ziemlich einfach:Lies alles aus der Tabelle und spuck es aus.

  |--Clustered Index Scan(OBJECT:([ee].[dbo].[mytable].[PK__mytable__3213E83F29C2D227]), ORDERED FORWARD)

Einfach aussehen bedeutet jedoch nicht, dass es einfach ist. Die Tabelle ist ziemlich groß und wir müssen viele Lesevorgänge durchführen, um alle Datensätze zurückzugeben:

SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.

(строк обработано: 1310720)
Table 'mytable'. Scan count 1, logical reads 2765, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 266 ms,  elapsed time = 11690 ms.

Kurz gesagt, die Paginierungsabfrage weiß einfach, wann sie aufhören muss.