sql >> Databasteknik >  >> RDS >> Sqlserver

Serversidesökning i SQL Server

CTE är inte (nödvändigtvis) "aktualiserad". Det är inte så att det oundvikligen kommer att kopiera alla rader någon annanstans och kommer att utföra andra operationer över kopian (även om det kan fungera så att optimeraren bestämmer att det är bättre).

Om vi ​​tar den här enkla frågan:

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

och titta på dess plan kommer vi att se något sånt här:

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

Här skannas posterna (i id ordning eftersom tabellen är klustrad på id ), tilldelade ROW_NUMBER (detta är vad Sequence Project gör) och skickas vidare till TOP som bara stoppar exekveringen när en viss tröskel nås (110 register i vårt fall).

Dessa 110 poster skickas till Filter som bara skickar posterna med rn mer än 100.

Själva frågan skannar bara 110 poster:

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.

på 3 sidor.

Låt oss nu se den opaginerade frågan:

SELECT  *
FROM    mytable
ORDER BY
        id

Den här är ganska enkel:läs allt från tabellen och spotta ut det.

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

Att se lätt ut betyder dock inte att det görs lätt. Tabellen är ganska stor och vi behöver läsa många gånger för att returnera alla poster:

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.

Så i ett nötskal vet sidnumreringsfrågan bara när den ska sluta.




  1. CakePHP kapslar två utvalda frågor

  2. SQL tidsskillnad inom en tabell

  3. Allvarliga problem med MySQL-frågans prestanda efter att ha lagt till villkor

  4. Ökar inställningen av NOT NULL på en kolumn i postgresql prestanda?