博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

如何写高效率的sql语句

Posted on 2009-03-02 13:41  雷雷  阅读(290)  评论(0编辑  收藏  举报

大型系统的生产环境,一般情况下,我们评价一条查询是否有效率,更多的是关注逻辑IO(至于为什么,回头补一篇)。我们常说,“要建彪悍的索引”、“要写高效的SQL”,其实最终目的就是在相同结果集情况下,尽可能减少逻辑IO。

http://www.it55.com在线教程

 


1.1     where条件的列上都得有统计信息
没统计信息SQLServer就无法估算不同查询计划开销优劣,而只能采用最稳妥的Scan(不管是table scan还是clustered index scan)。一般情况下我们不会犯这种错误——where条件里不使用非索引列是个常识。索引上的统计信息是无法删除的。 免费资源http://www.it55.com

1.2     尽量不使用不等于(!=)或者NOT逻辑运算符。
这条规则被广为传颂,原因据联机文档和百敬同学的书讲,也是SQLServer无法评估不同查询计划开销的优劣。但是SqlServer2k5聪明了很多,试验发现尽管用了!=或者not,查询还是会被优化。如下:

vd;k;l http://www.it55.com rdfg

 

create table tb1

vd;k;l http://www.it55.com rdfg

 

(

免费壁纸下载http://www.it55.com

 

    col1 int identity(1,1) primary key, 免费壁纸下载http://www.it55.com

    col2 int not null, 免费壁纸下载http://www.it55.com

    col3 varchar(64) not null

免费设计素材下载http://www.it55.com

 

) 免费网页模版下载http://www.it55.com

create index ix_tb1_col2 on tb1

免费设计素材下载http://www.it55.com

 

(

http://www.it55.com

 

    col2

vd;k;l http://www.it55.com rdfg

 

) 精美韩国模版下载http://www.it55.com

create index ix_tb1_col3 on tb1 IT资讯之家 http://www.it55.com

(

sflj http://www.it55.com kg^&fgd

 

    col3 免费设计素材下载http://www.it55.com

) 免费资源http://www.it55.com

declare @f int 免费网页模版下载http://www.it55.com

set @f = 0 vd;k;l http://www.it55.com rdfg

while @f < 9999 免费壁纸下载http://www.it55.com

begin 精美韩国模版下载http://www.it55.com

    insert into tb1 (col2, col3) values(1, 'ssdd')

45398 http://www.it55.com it55学习IT知识,享受IT生活 4dfkjn

 

    set @f = @f + 1 http://www.it55.com/

end

http://www.it55.com

 

insert into tb1 (col2, col3) values(0, 'aadddd')

IT资讯之家 http://www.it55.com

 

insert into tb1 (col2, col3) values(2, 'bbddd') 免费设计素材下载http://www.it55.com

insert into tb1 (col2, col3) values(3, 'bbaaddddddaa')

45398 http://www.it55.com it55学习IT知识,享受IT生活 4dfkjn

 

通过上述代码,各位可以看到数据分布。col2值为1的有9999条;col2值为0、2、3的分别有1条。

免费壁纸下载http://www.it55.com

 

按照本条规则,!= 和NOT带来的应该是个scan操作,但实际情况是:

免费资源http://www.it55.com

SQL2k5很聪明,它依据统计信息分析得出来,应该采用index seek而不是index scan。(稍微解释解释index seek和index scan:索引是一颗B树,index seek是查找从B树的根节点开始,一级一级找到目标行。index scan则是从左到右,把整个B树遍历一遍。假设唯一的目标行位于索引树(假设是非聚集索引,树深度2,叶节点占用k页物理存储)最右的叶节点上(如上例)。index seek引起的IO是4,而index scan引起的IO是K,性能差别巨大。关于索引,可以仔细读读联机文档关于物理数据库体系结构部分)。 免费矢量图片素材下载http://www.it55.com

1.3     查询条件中不要包含运算
这些运算包括字符串连接(如:select * from Users where UserName + ‘pig’ = ‘张三pig’),通配符在前面的Like运算(如:select * from tb1 where col4 like ‘%aa’),使用其他用户自定义函数、系统内置函数、标量函数等等(如:select * from UserLog where datepart(dd, LogTime) = 3)。

免费网页模版下载http://www.it55.com

 

         SQLServer在处理以上语句时,一样没办法估算开销。最终结果当然是clustered index scan或者table scan了。

(编辑:IT资讯之家 www.it55.com

返回顶部
共8页: 上一页 1 [2] [3] [4] [5] [6] [7] [8] 下一页