欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

SQLServer2012分页语句执行分析

程序员文章站 2023-11-16 08:09:10
sqlserver2012分页语句执行分析   现在让我们来看看,究竟是什么导致sqlserver不能按需取数呢?   1. 先来看看语句,及其执行计划...

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

 

SQLServer2012分页语句执行分析

 

2. 分析

 

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

 

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

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

 

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

 

SQLServer2012分页语句执行分析

 

分析至此,认为并行计算在这里拖后腿了。如果没有并行计算,由于在排序列上是有索引的,取数都是按排序的规则进行,那么一旦取得了需要的结果子集,处理就可以结束了。也就可以避免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秒啊,坑爹啊,有木有。。。)

 

SQLServer2012分页语句执行分析

 

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

 

4. 建议

 

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

 

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