sql >> Database >  >> RDS >> Sqlserver

Paging aan de serverzijde in SQL Server

De CTE is niet (noodzakelijkerwijs) "geactualiseerd". Het is niet zo dat het onvermijdelijk alle rijen ergens anders zal kopiëren en andere bewerkingen zal uitvoeren over de kopie (hoewel het zich zo kan gedragen dat het optimalisatieprogramma beslist dat het beter is).

Als we deze eenvoudige vraag nemen:

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

en kijk naar het plan, we zien zoiets als dit:

  |--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 worden de records gescand (in id bestel als de tabel is geclusterd op id ), toegewezen aan de ROW_NUMBER (dit is wat Sequence Project doet) en doorgegeven aan TOP die de uitvoering gewoon stopt wanneer een bepaalde drempel is bereikt (110 records in ons geval).

Die 110 records worden doorgegeven aan Filter die alleen de records doorgeeft met rn groter dan 100.

De query zelf scant alleen 110 records:

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.

in 3 pagina's.

Laten we nu de niet-gepagineerde zoekopdracht bekijken:

SELECT  *
FROM    mytable
ORDER BY
        id

Deze is vrij eenvoudig:lees alles van de tafel en spuug het uit.

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

Gemakkelijk kijken betekent echter niet gemakkelijk gedaan. De tabel is vrij groot en we moeten veel lezen om alle records terug te geven:

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.

Kortom, de pagineringsquery weet precies wanneer hij moet stoppen.




  1. Voorkeur MySQL-tools

  2. Zoek een gebruikerspositie op een geordende SQL-tabel

  3. Waarom lopen de opdrachten nog steeds niet synchroon; je kunt deze opdracht nu niet uitvoeren fout

  4. hoe tekst in cel te vervangen door gegevens in een andere tabel in mysql