sql >> Databáze >  >> RDS >> Sqlserver

Stránkování na straně serveru v SQL Server

CTE není (nezbytně) "aktualizovaný". Nejde o to, že nevyhnutelně zkopíruje všechny řádky jinam a bude nad kopií provádět další operace (i když se může chovat tak, že optimalizátor rozhodne, že je to lepší).

Pokud vezmeme tento jednoduchý dotaz:

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

a podívejte se na jeho plán, uvidíme něco takového:

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

Zde jsou záznamy naskenovány (v id pořadí, protože tabulka je seskupená na id ), přiřazeno číslo ROW_NUMBER (toto je Sequence Project dělá) a předán do TOP který pouze zastaví provádění při dosažení určité prahové hodnoty (110 v našem případě záznamy).

Těchto 110 záznamů je předáno do Filter který pouze předává záznamy s rn větší než 100.

Samotný dotaz skenuje pouze 110 záznamy:

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 stránkách.

Nyní se podívejme na nestránkovaný dotaz:

SELECT  *
FROM    mytable
ORDER BY
        id

Tohle je docela jednoduché:přečtěte si vše ze stolu a vyplivněte to.

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

Nicméně, hledat snadno neznamená udělat snadno. Tabulka je poměrně velká a musíme provést mnoho čtení, abychom vrátili všechny záznamy:

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.

Stručně řečeno, stránkovací dotaz prostě ví, kdy přestat.




  1. Jak vynutit referenční integritu u dědičnosti jedné tabulky?

  2. Jak zjistit, který sloupec při vložení vyvolává aritmickou chybu přetečení?

  3. Doktrína generující dotaz s nesprávným aliasem tabulky

  4. Vysvětlete Plán Cost Pain Point