程序内外不同的查询计划
Different query plans outside and inside procedure
我有一个在 SSMS 中快速而在过程中缓慢的查询(名称已更改,但意义保持不变):
select w.shipper_id, w.date,
sum (wp.qty * #p.pkg_qty) qty, count (distinct w.w_id) dc
from db..waybills w
join db..waybillproducts wp with (index (w_id_and_prod_id)) on w.w_id = wp.w_id
join #p on wp.prod_id = #p.prod_id
where w.type in (1, 2)
and w.date between @dateFrom and @dateTo
and w.shipper_id > 0
group by w.shipper_id, w.date
having sum (wp.qty * #p.pkg_qty) != 0;
计划:image
在 SSMS 计划中,“w_id_and_prod_id”中的索引查找具有谓词“PROBE([Opt_Bitmap1014],[db].[dbo].[WaybillProducts].[prod_id ] 作为 [wp].[prod_id],N'[IN ROW]')”。显然,有了它,最初只从db..waybillproducts
中选择存在于#p
中的产品,这大大减少了行数。但服务器不会在程序中执行此操作。
索引“w_id_and_prod_id”被定义为非集群 ON db..waybillproducts (w_id) INCLUDE (prod_id).
SET ARITHABORT ON 和 OPTION(RECOMPILE)不改变计划。也许有人可以帮助解决这个问题。
解决方案
选项(针对未知进行优化)
很可能您正在为存储过程中的参数嗅探而苦恼,因为数据分布不均。
当你想测试存储过程时,你必须将它们作为 sp 进行测试,如果你将所有参数替换为 values ,SQL 将创建一个新计划。
我有一个在 SSMS 中快速而在过程中缓慢的查询(名称已更改,但意义保持不变):
select w.shipper_id, w.date,
sum (wp.qty * #p.pkg_qty) qty, count (distinct w.w_id) dc
from db..waybills w
join db..waybillproducts wp with (index (w_id_and_prod_id)) on w.w_id = wp.w_id
join #p on wp.prod_id = #p.prod_id
where w.type in (1, 2)
and w.date between @dateFrom and @dateTo
and w.shipper_id > 0
group by w.shipper_id, w.date
having sum (wp.qty * #p.pkg_qty) != 0;
计划:image
在 SSMS 计划中,“w_id_and_prod_id”中的索引查找具有谓词“PROBE([Opt_Bitmap1014],[db].[dbo].[WaybillProducts].[prod_id ] 作为 [wp].[prod_id],N'[IN ROW]')”。显然,有了它,最初只从db..waybillproducts
中选择存在于#p
中的产品,这大大减少了行数。但服务器不会在程序中执行此操作。
索引“w_id_and_prod_id”被定义为非集群 ON db..waybillproducts (w_id) INCLUDE (prod_id).
SET ARITHABORT ON 和 OPTION(RECOMPILE)不改变计划。也许有人可以帮助解决这个问题。
解决方案
选项(针对未知进行优化)
很可能您正在为存储过程中的参数嗅探而苦恼,因为数据分布不均。 当你想测试存储过程时,你必须将它们作为 sp 进行测试,如果你将所有参数替换为 values ,SQL 将创建一个新计划。