Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 一个执行大量读取但计划正常的查询_Sql Server_Sql Execution Plan - Fatal编程技术网

Sql server 一个执行大量读取但计划正常的查询

Sql server 一个执行大量读取但计划正常的查询,sql-server,sql-execution-plan,Sql Server,Sql Execution Plan,我在SQL Server 2008 R2的特定查询中遇到了一个奇怪的行为。 我有一个可以读取1900万次的查询,非常耗时,当我尝试检查它的缓存计划时,该计划是正常的,没有任何问题 在执行DBCC FREEPROCCACHE之后,相同的查询执行400次读取(耗时16毫秒)。 结论是,不知何故,查询是以错误的计划执行的,但这不是我从SQL Server获得的信息 有人知道发生了什么事吗? 以下是我用来提取计划的查询: SELECT sqltext.TEXT, sqlplan.query_plan,

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

在执行DBCC FREEPROCCACHE
之后,相同的查询执行400次读取(耗时16毫秒)。 结论是,不知何故,查询是以错误的计划执行的,但这不是我从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

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


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

过时的分布统计数据也可能导致这种行为。还有零散的指数。可能还有其他一些可能性——在看不到实际执行计划的情况下,猜测可能永远持续下去


但是,您可以尝试在查询中添加<代码>优化未知的选项,并查看它是否有帮助。

您也可以考虑在DBA.STACKExchange .com上询问这一点,以防您还没有这样做。我只是这样做了,谢谢您的建议。请将两个运行的统计IO输出张贴。请将该信息编辑到您的问题中,即使计划形状可能保持不变或重复使用,它也可能受到参数嗅探或扭曲统计数据的影响。仅仅因为它是同一个计划并不意味着它是正确的计划。如果你能发布两次执行的实际计划,那将非常有帮助。
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%'