Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Stronicowanie po stronie serwera w SQL Server

CTE nie jest (koniecznie) „aktualizowany”. Nie chodzi o to, że nieuchronnie skopiuje wszystkie wiersze w inne miejsce i wykona inne operacje na kopii (chociaż może zachowywać się tak, że optymalizator uzna, że ​​jest to lepsze).

Jeśli weźmiemy to proste zapytanie:

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

i spójrz na jego plan, zobaczymy coś takiego:

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

Tutaj rekordy są skanowane (w id kolejność, ponieważ tabela jest zgrupowana na id ), przypisał ROW_NUMBER (to właśnie Sequence Project robi) i przekazano do TOP który zatrzymuje wykonanie po osiągnięciu określonego progu (110 rekordy w naszym przypadku).

Te 110 rekordów jest przekazywanych do Filter który przekazuje rekordy tylko za pomocą rn większe niż 100.

Samo zapytanie skanuje tylko 110 rekordy:

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.

na 3 stronach.

Zobaczmy teraz zapytanie niepodzielone na strony:

SELECT  *
FROM    mytable
ORDER BY
        id

Ta jest całkiem prosta:przeczytaj wszystko ze stołu i wypluj.

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

Jednak łatwe szukanie nie oznacza łatwego wykonania. Tabela jest dość duża i musimy wykonać wiele odczytów, aby zwrócić wszystkie rekordy:

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.

Krótko mówiąc, zapytanie o paginację po prostu wie, kiedy przestać.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Dodanie kolumny między dwiema innymi kolumnami w serwerze SQL

  2. SQL 2 liczy się z innym filtrem

  3. Jak zwiększyć licznik w wyborze?

  4. Wstaw obraz do pola obrazu SQL Server 2005 używając tylko SQL

  5. SMALLDATETIMEFROMPARTS() Przykłady w SQL Server (T-SQL)