首页 文章

一个执行大量读取的查询,但计划是可以的

提问于
浏览
1

我在 SQL Server 2008 R2 中的特定查询中遇到了奇怪的行为 . 我有一个查询,它执行了1900万次读取并且非常耗时,当我尝试检查其缓存计划时,该计划是可以的,没有任何问题 .

执行 DBCC FREEPROCCACHE 后,相同的查询执行400次读取(占用16 ms) . 结论是,查询以错误的计划执行,但这不是我从SQL Server获得的信息 .

有谁知道发生了什么事?在下面查找我用于提取计划的查询:

SELECT
sqltext.TEXT,
sqlplan.query_plan,
req.session_id [Session ID],
p.kpid [Thread ID],
p.program_name,
req.status,
req.command,
req.cpu_time,
req.logical_reads,
req.blocking_session_id,
req.transaction_id,
req.total_elapsed_time,
req.wait_resource
FROM sys.dm_exec_requests req inner join
     sys.sysprocesses p on req.session_id = p.spid
     CROSS APPLY sys.dm_exec_query_plan(req.plan_handle) AS sqlplan
     CROSS APPLY sys.dm_exec_sql_text(req.sql_handle) AS sqltext

SELECT db.name,
cp.objtype AS ObjectType,
OBJECT_NAME(st.objectid,st.dbid) AS ObjectName,
cp.usecounts AS ExecutionCount,
st.TEXT AS QueryText,
qp.query_plan AS QueryPlan
FROM sys.dm_exec_cached_plans AS cp
CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle) AS qp
CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) AS st 
INNER JOIN sys.sysdatabases db on st.dbid = db.dbid
where st.TEXT like '%part_of_query%'

另一个信息是查询计划在free cache命令之前和之后是相同的 .

Image of the Execution Plan

1 回答

  • 1

    很多事情都会以这种方式影响查询 . 最常见的可能是参数嗅探 . 当第一次执行查询时,使用使用这些确切参数值获得的基数估计来构建计划 . 因此,如果第一次运行中使用的参数值非常有选择性,优化器可能会利用嵌套循环进行连接 . 所以下一次,使用另一个影响一半表的值,这个缓存的计划将非常无效,因为在这种情况下哈希或合并连接更好 .

    过时的分布统计也可能导致这种行为 . 以及碎片指数也是如此 . 可能还有其他一些可能性 - 没有看到实际的执行计划,猜测可以永远持续下去 .

    但您可以尝试在查询中添加 optimize for unknown 选项,看看它是否有帮助 .

相关问题