sql >> Database teknologi >  >> RDS >> Sqlserver

Serversidesøgning i SQL Server

CTE er ikke (nødvendigvis) "aktualiseret". Det er ikke sådan, at det uundgåeligt vil kopiere alle rækker andre steder og vil udføre andre handlinger over kopien (selvom det kan opføre sig, så det optimeringsværktøjet beslutter, at det er bedre).

Hvis vi tager denne enkle forespørgsel:

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

og se på dens plan, vil vi se noget som dette:

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

Her scannes posterne (i id rækkefølge, da tabellen er grupperet på id ), tildelt ROW_NUMBER (det er hvad Sequence Project gør) og videregivet til TOP som bare stopper eksekveringen, når en bestemt tærskel er nået (110 optegnelser i vores tilfælde).

Disse 110 poster sendes til Filter som kun sender posterne med rn mere end 100.

Selve forespørgslen scanner kun 110 optegnelser:

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 sider.

Lad os nu se den upaginerede forespørgsel:

SELECT  *
FROM    mytable
ORDER BY
        id
 

Denne er ret enkel:læs alt fra tabellen og spyt det ud.

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

At se let ud betyder dog ikke gjort let. Tabellen er ret stor, og vi skal læse mange gange for at returnere alle 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 en nøddeskal ved pagineringsforespørgslen bare, hvornår den skal stoppe.




  1. Hvordan formaterer man kun de poster, for hvilke ORA-01843 ikke er smidt?

  2. Oracle-skemabruger kan ikke oprette tabel i procedure

  3. Fjern en karakter fra en given position på Oracle

  4. Hvorfor får jeg MySQL-fejl #1312, når jeg bruger en simpel lagret procedure?