查询表单对进入参数嗅探有影响吗?
Does query form have an influence on getting into parameter sniffing?
最近,我的一位从事 SQL 开发工作的同事遇到了这样的问题:一个过程 运行 在所有环境中都很好,但生产环境却拥有最多的资源。 parameter sniffing 的典型案例,但分析器表明整个过程中只有一个查询执行时间非常长:
UPDATE a
SET status_id = 6
FROM usr.tpt_udef_article_grouping_buffer a
LEFT JOIN (SELECT DISTINCT buying_domain_id, suppl_no FROM usr.buyingdomain_supplier_article) b ON a.buying_domain_id = b.buying_domain_id
AND a.suppl_no = b.suppl_no
WHERE a.tpt_file_id = @tpt_file_id
AND a.status_id IS NULL
AND b.suppl_no IS NULL
由于我偏向于开发(我没有多少管理经验),我建议重写这个查询:
将LEFT JOIN (SELECT DISTINCT ...)
替换为NOT EXISTS (SELECT 1 ...)
在 table usr.tpt_udef_article_grouping_buffer
上放置适当的索引(SSMS 建议当查询 运行 在程序之外时减少 95% 的工作量)
此外,过程中的多个查询共享相同的模式。
我知道参数嗅探与运行创建(重新)创建程序后第一次创建程序时的计划构建更相关,我认为它也受到高圈复杂度的青睐。
我的问题是:
程序中查询的编写方式(从一开始就糟糕的执行计划)是否有利于参数嗅探 运行ce 或只会恶化它们的效果?
你这里唯一的参数是a.tpt_file_id = @tpt_file_id
,如果这是参数嗅探,那么情况必须是tpt_file_id有几千条(或更多)记录,并且肯定有很少(或none)。
您在生产环境中获得与测试环境不同的计划的另一个原因是机器不同。在生产环境中,您通常有更多的内存和更多的 CPU / 核心,导致优化器选择不同的计划,当然如果表中的行数不相同,它当然会导致完全不同的计划。
您可以使用 option (recompile)
检查计划是否更改或查看计划缓存以了解用于创建计划的参数值。在计划最左边的对象的属性中可以看到。
将 select distinct 更改为 exists 子句可能是个好主意,当然还可以正确索引表。
最近,我的一位从事 SQL 开发工作的同事遇到了这样的问题:一个过程 运行 在所有环境中都很好,但生产环境却拥有最多的资源。 parameter sniffing 的典型案例,但分析器表明整个过程中只有一个查询执行时间非常长:
UPDATE a
SET status_id = 6
FROM usr.tpt_udef_article_grouping_buffer a
LEFT JOIN (SELECT DISTINCT buying_domain_id, suppl_no FROM usr.buyingdomain_supplier_article) b ON a.buying_domain_id = b.buying_domain_id
AND a.suppl_no = b.suppl_no
WHERE a.tpt_file_id = @tpt_file_id
AND a.status_id IS NULL
AND b.suppl_no IS NULL
由于我偏向于开发(我没有多少管理经验),我建议重写这个查询:
将
LEFT JOIN (SELECT DISTINCT ...)
替换为NOT EXISTS (SELECT 1 ...)
在 table
usr.tpt_udef_article_grouping_buffer
上放置适当的索引(SSMS 建议当查询 运行 在程序之外时减少 95% 的工作量)
此外,过程中的多个查询共享相同的模式。
我知道参数嗅探与运行创建(重新)创建程序后第一次创建程序时的计划构建更相关,我认为它也受到高圈复杂度的青睐。
我的问题是:
程序中查询的编写方式(从一开始就糟糕的执行计划)是否有利于参数嗅探 运行ce 或只会恶化它们的效果?
你这里唯一的参数是a.tpt_file_id = @tpt_file_id
,如果这是参数嗅探,那么情况必须是tpt_file_id有几千条(或更多)记录,并且肯定有很少(或none)。
您在生产环境中获得与测试环境不同的计划的另一个原因是机器不同。在生产环境中,您通常有更多的内存和更多的 CPU / 核心,导致优化器选择不同的计划,当然如果表中的行数不相同,它当然会导致完全不同的计划。
您可以使用 option (recompile)
检查计划是否更改或查看计划缓存以了解用于创建计划的参数值。在计划最左边的对象的属性中可以看到。
将 select distinct 更改为 exists 子句可能是个好主意,当然还可以正确索引表。