Mennyi idő alatt állt elő a Query Plan?
Az utóbbi Meetup eseményeken egy kolléga arra volt kíváncsi, hogy mennyi idő alatt áll elő egy query plan. Akkor és ott helyben a választ nem tudtam. Miközben a monitoring riportjaimat készítettem, felmerült ugyan ez a kérdés és kicsit utánanéztem. A plan xml-jében benne van az információ, hurrá :-), ettől egyszerübb nem is lehetne. Ezt és egyéb hasznos infókat az alábbi lekérdezés segítségével ki lehet szedni:
1;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp)
2SELECT
3 CONVERT (bigint, stmt_simple.stmt_node.value('(./@StatementEstRows)[1]', 'decimal(28,10)')) AS stmt_est_rows,
4 stmt_simple.stmt_node.value('(./@StatementOptmLevel)[1]', 'varchar(30)') AS stmt_optimization_level,
5 stmt_simple.stmt_node.value('(./@StatementOptmEarlyAbortReason)[1]', 'varchar(30)') AS stmt_optimization_early_abort_reason,
6 stmt_simple.stmt_node.value('(./@StatementSubTreeCost)[1]', 'float') AS stmt_est_subtree_cost,
7 stmt_simple.stmt_node.value('(./@StatementText)[1]', 'nvarchar(max)') AS stmt_text,
8 stmt_simple.stmt_node.value('(./@ParameterizedText)[1]', 'nvarchar(max)') AS stmt_parameterized_text,
9 stmt_simple.stmt_node.value('(./@StatementType)[1]', 'varchar(30)') AS stmt_type,
10 stmt_simple.stmt_node.value('(./@PlanGuideName)[1]', 'varchar(30)') AS plan_guide_name,
11 stmt_simple.stmt_node.value('(./sp:QueryPlan/@CachedPlanSize)[1]', 'int') AS plan_size,
12 stmt_simple.stmt_node.value('(./sp:QueryPlan/@CompileTime)[1]', 'bigint') AS plan_compile_time_ms,
13 stmt_simple.stmt_node.value('(./sp:QueryPlan/@CompileCPU)[1]', 'bigint') AS plan_compile_cpu,
14 stmt_simple.stmt_node.value('(./sp:QueryPlan/@CompileMemory)[1]', 'int') AS plan_compile_memory
15FROM
16 sys.dm_exec_cached_plans
17CROSS APPLY
18 sys.dm_exec_query_plan([plan_handle]) AS p
19CROSS APPLY
20 p.query_plan.nodes ('/sp:ShowPlanXML/sp:BatchSequence/sp:Batch/sp:Statements/sp:StmtSimple') as stmt_simple (stmt_node)
21ORDER BY
22 10 DESC
Az alábbi oszlopokat adja vissza:
- stmt_est_rows: a becsüt sorok száma, amit a lekrédezés vissza fog adni
- stmt_optimization_level: ez a FULL és a TRIVIAL értékeket veheti fel. Az utóbbi azt jelenti, hogy az optimizer szerint egy terv lehet optimális.
- stmt_optimization_early_abort_reason: megmutatja, hogy a terv létrehozása mirét szakadt meg. Ez 3 értéket vehet fel:
- GoodEnoughPlanFound: ez azt jelenti, hogy a terv létrehozási idő maximumán belül sikerült egy elfogadható végrehajtási tervet létrehozni,
- TimeOut: nem sikerült időn belül optimális tervet létrehozni,
- MemoryLimitExceeded: ennél az esetnél kicsit izgulnék ;-). Itt nagy valószínűséggel nincs elegendő memória a szerverbe vagy túls ok memóriát - foglal a plan cache, stb. Ezt ki kell nyomozni.
- stmt_est_subtree_cost: a parancs végrehajtásának várható költsége.
- stmt_text: a végrehajtandó parancs.
- stmt_parameterized_text:
- stmt_type: a végrehajtandó parancs típusa. pl.: SELECT, SELECT INTO, DELETE, INSERT EXEC.
- plan_guide_name: ha plan guide van használatban, akkor annak a neve.
- plan_size: a terv mérete.
- plan_compile_time_ms: a végrehajtási terv előállításához szükséges idő
- plan_compile_cpu: a terv létrehozásakor felhasznált cpu
- plan_compile_memory: a terv létrehozásakor felhasznált memória
A fenti lekérdezés éles rendszeren sokáig tarthat és befolyásolhatja a memória-használatot, illetve a teljesítményt. A lekérdezés lefuttatása csak saját felelősségre történhet!