Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Pagination côté serveur dans SQL Server

Le CTE n'est pas (nécessairement) "actualisé". Ce n'est pas qu'il copiera inévitablement toutes les lignes ailleurs et effectuera d'autres opérations sur la copie (bien qu'il puisse se comporter de telle sorte que l'optimiseur décide que c'est mieux).

Si nous prenons cette requête simple :

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

et regardez son plan, nous verrons quelque chose comme ceci :

  |--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)

Ici, les enregistrements sont scannés (en id ordre car la table est regroupée sur id ), a attribué le ROW_NUMBER (c'est ce que Sequence Project fait) et transmis à TOP qui arrête juste l'exécution lorsqu'un certain seuil est atteint (110 records dans notre cas).

Ces 110 enregistrements sont transmis à Filter qui ne passe que les enregistrements avec rn supérieur à 100.

La requête elle-même ne scanne que 110 enregistrements :

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.

en 3 pages.

Voyons maintenant la requête non paginée :

SELECT  *
FROM    mytable
ORDER BY
        id

Celui-ci est assez simple :lisez tout ce qui se trouve sur le tableau et recrachez-le.

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

Cependant, regarder facilement ne signifie pas faire facilement. Le tableau est assez volumineux et nous devons effectuer plusieurs lectures pour renvoyer tous les enregistrements :

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.

Donc, en un mot, la requête de pagination sait juste quand s'arrêter.