日期:2014-05-19  浏览次数:20881 次

百分!优化SQL语句时遇见的怪异问题
一条SQL语句,不添加order   by   ,则查询出结果需要1S左右的时间,而添加order   by后,则查询出结果需要20S左右的时间。

通过set   statistics   io   on查看,
结果如下:

--不添加order   by
表   'BAS_CONTRACT_CONTENT '。扫描计数   40,逻辑读   136   次,物理读   0   次,预读   0   次。
表   'BAS_USR '。扫描计数   20,逻辑读   53   次,物理读   0   次,预读   0   次。
表   'BAS_ACCOUNT_ITEM '。扫描计数   9088,逻辑读   51963   次,物理读   16   次,预读   0   次。
表   'BAS_CONTRACT_ZX '。扫描计数   9030,逻辑读   36250   次,物理读   5   次,预读   0   次。
表   'BAS_CONTRACT_REP '。扫描计数   9030,逻辑读   18125   次,物理读   0   次,预读   0   次。
表   'BAS_CONTRACT '。扫描计数   1,逻辑读   1507   次,物理读   0   次,预读   0   次。

--添加order   by
表   'BAS_CONTRACT_CONTENT '。扫描计数   40,逻辑读   216   次,物理读   0   次,预读   0   次。
表   'BAS_USR '。扫描计数   20,逻辑读   53   次,物理读   0   次,预读   0   次。
表   'BAS_CONTRACT '。扫描计数   2,逻辑读   20781   次,物理读   0   次,预读   8   次。
表   'BAS_CONTRACT_ZX '。扫描计数   1,逻辑读   466   次,物理读   6   次,预读   104   次。
表   'BAS_ACCOUNT_ITEM '。扫描计数   1,逻辑读   986   次,物理读   0   次,预读   0   次。
表   'Worktable '。扫描计数   677,逻辑读   1130   次,物理读   0   次,预读   0   次。
表   'BAS_CONTRACT_REP '。扫描计数   1,逻辑读   11   次,物理读   0   次,预读   0   次。

可以看到不添加order   by比添加order   by   后的逻辑读的次数高出许多,但是查询速度却快很多,这与我平时看到的资料的描述不符,请各位高手帮忙看看,有什么情况会出现这个情况!

另:order   by三个字段A/B/C,A/B组成一个索引,C也设置了索引!

------解决方案--------------------
'BAS_CONTRACT_CONTENT '
这个表的逻辑读次数在加了ORDER BY之后,高了很多!
=======================
这个表的数据量应该很大,而且你从这个表取的字段量也应该很多吧?


逻辑读次数多不一定速度就慢
一个只有10条数据的表、逻辑读100次、取1个类型为int的字段(平均字节数为4);(A)
一个10000条数据的表、逻辑读10次、取10个类型为int等组合的字段(平均字节数为30);(B)

A的速度也应该会比B快。


------解决方案--------------------
对数据库页的请求,该请求中 SQL Server 必须将所请求页从磁盘传输到 SQL Server 缓冲区池。所有读取页的尝试都称作逻辑读取。如果该页已在缓冲区中,则不存在由逻辑读取生成的相关物理读取。物理读取的数目从不会超过逻辑读取的数目。在调整良好的 SQL Server 实例中,逻辑读取的数目通常远高于物理读取的数目。

由此可见,逻辑读是从从数据高速缓存读取的页数,物理读是从磁盘读取的页数,而预读则是为查询放入高速缓存的页数,所以物理读才是决定效率的主要因素(这里单指IO)

另外,做个测试,表1,字段a为聚集索引
select * from table1,和select * from table1 order by a
2条语句的效率或者执行计划应该是一样的,都只扫描聚集索引

如果字段b无索引,select * from table1 order by b,则会执行sort排序工作,这会产生大量的IO操作,对效率影响很大

如果字段b为非聚集索引, select * from table1 order by b,则会对非聚集索引进行排序,这步的IO操作介于聚集索引和无索引之间