SQLServer2012分页语句执行分析

sqlserver2012分页语句执行分析

 

现在让我们来看看,究竟是什么导致sqlserver不能按需取数呢?
 

1. 先来看看语句,及其执行计划

select billdate, sum([qty]) posinqty
from rtldetail a,rtlbill b 
where a.billno = b.billno  and billdate>='2009-09-25 00:00:00' and billdate<='2012-09-25 23:59:59'
group by billdate
order by billdate
offset 10 row fetch next 20 rows only;

 

 

耗时:18 s

 

 

2. 分析

 

从执行计划中,可以看到所有的处理都使用了并行处理。

 

这样就存在一个问题:并行计算时,各处理器如何知道自己处理的部分会有多少条最后出现在结果集中?

如果不知道,就只能各自处理自己的部分,然后汇总起来,再取需要的部分。

 

从上图的执行计划中可以看出,第一个并行计算,即红框标注的部分是一个roundrobin的并行任务分配过程,16个核,每个负责从ix_rtlbill_billdate中取出1/16的数据,进行计算。再看执行计划的分页部分就更清晰一些了,每个并行部分处理完了所有的记录,汇总起来,再通过top方式取得需要的数据部分。

 

 

分析至此,认为并行计算在这里拖后腿了。如果没有并行计算,由于在排序列上是有索引的,取数都是按排序的规则进行,那么一旦取得了需要的结果子集,处理就可以结束了。也就可以避免io及cpu的浪费。

 

3. 验证一下想法,强制设置最大并行度为1,再执行语句

 

select billdate, sum([qty]) posinqty
from rtldetail a,rtlbill b 
where a.billno = b.billno  and billdate>='2009-09-25 00:00:00' and billdate<='2012-09-25 23:59:59'
group by billdate
order by billdate
offset 10 row fetch next 20 rows only option (maxdop 1);

 

耗时: 1s     (并行时18s秒啊,坑爹啊,有木有。。。)

 

 

好的,这个效率终于能和window下的mariadb媲美了,可人家在linux下执行只需要 265ms 啊。 呵呵,这个是后话了。

 

4. 建议

 

(1)对微软的建议:在生成分页语句的执行计划时,可以先比较下并行的成本和非并行的成本,如果差距太大,就不要用parallel的方式了;

 

(2)对使用者的建议:如果你的分页语句耗时太长,又常常只获取前面的部分分页内容,那么就把并行关了吧。至少在微软做出优化之前。

 

(0)
上一篇 2022年3月21日
下一篇 2022年3月21日

相关推荐