仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 779|回复: 7
打印 上一主题 下一主题

[学习教程] MSSQL教程之怎样让你的SQL运转得更快

[复制链接]
若天明 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-16 22:39:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
InnoDB数据表的索引,与InnoDB数据表相比,在InnoDB数据表上,索引对InnoDB数据表的重要性要大得多。在InnoDB数据表上,索引不仅会在搜索数据记录时发挥作用,还是数据行级锁定机制的苊、基础。


人们在利用SQL时常常会堕入一个误区,即太存眷于所得的了局是不是准确,而疏忽了分歧的完成办法之间大概存在的功能差别,这类功能差别在年夜型的或是庞大的数据库情况中(如联机事件处置OLTP或决议撑持体系DSS)中体现得尤其分明。笔者在事情理论中发明,不良的SQL常常来自于不得当的索引计划、不充份的毗连前提和不成优化的where子句。在对它们举行得当的优化后,其运转速率有了分明地进步!上面我将从这三个方面分离举行总结:

为了更直不雅地申明成绩,一切实例中的SQL运转工夫均经由测试,不凌驾1秒的均暗示为(<1秒)。

测试情况--
主机:HPLHII
主频:330MHZ
内存:128兆
操纵体系:Operserver5.0.4
数据库:Sybase11.0.3

1、分歧理的索引计划
例:表record有620000行,试看在分歧的索引下,上面几个SQL的运转情形:
1.在date上建有一非个聚集索引

selectcount(*)fromrecordwheredate>
19991201anddate<19991214andamount>
2000(25秒)
selectdate,sum(amount)fromrecordgroupbydate
(55秒)
selectcount(*)fromrecordwheredate>
19990901andplacein(BJ,SH)(27秒)

剖析:
date上有大批的反复值,在非聚集索引下,数据在物理上随机寄存在数据页上,在局限查找时,必需实行一次表扫描才干找到这一局限内的全体行。

2.在date上的一个聚集索引

selectcount(*)fromrecordwheredate>
19991201anddate<19991214andamount>
2000(14秒)
selectdate,sum(amount)fromrecordgroupbydate
(28秒)
selectcount(*)fromrecordwheredate>
19990901andplacein(BJ,SH)(14秒)

剖析:
在聚集索引下,数据在物理上按按次在数据页上,反复值也分列在一同,因此在局限查找时,能够先找到这个局限的起末点,且只在这个局限内扫描数据页,制止了年夜局限扫描,进步了查询速率。

3.在place,date,amount上的组合索引

selectcount(*)fromrecordwheredate>
19991201anddate<19991214andamount>
2000(26秒)
selectdate,sum(amount)fromrecordgroupbydate
(27秒)
selectcount(*)fromrecordwheredate>
19990901andplacein(BJ,SH)(<1秒)

剖析:
这是一个不很公道的组合索引,由于它的前导列是place,第一和第二条SQL没有援用place,因而也没有益用上索引;第三个SQL利用了place,且援用的一切列都包括在组合索引中,构成了索引掩盖,以是它的速率长短常快的。

4.在date,place,amount上的组合索引

selectcount(*)fromrecordwheredate>
19991201anddate<19991214andamount>
2000(<1秒)
selectdate,sum(amount)fromrecordgroupbydate
(11秒)
selectcount(*)fromrecordwheredate>
19990901andplacein(BJ,SH)(<1秒)

剖析:
这是一个公道的组合索引。它将date作为前导列,使每一个SQL都能够使用索引,而且在第一和第三个SQL中构成了索引掩盖,因此功能到达了最优。

5.总结:

缺省情形下创建的索引长短聚集索引,但偶然它并非最好的;公道的索引计划要创建在对各类查询的剖析和展望上。一样平常来讲:

①.有大批反复值、且常常有局限查询

(between,>,<,>=,<=)和orderby
、groupby产生的列,可思索创建聚集索引;

②.常常同时存取多列,且每列都含有反复值可思索创建组合索引;

③.组合索引要只管使关头查询构成索引掩盖,其前导列必定是利用最频仍的列。

2、不充份的毗连前提:
例:表card有7896行,在card_no上有一个非会萃索引,表account有191122行,在account_no上有一个非会萃索引,试看在分歧的表毗连前提下,两个SQL的实行情形:

selectsum(a.amount)fromaccounta,
cardbwherea.card_no=b.card_no(20秒)

将SQL改成:
selectsum(a.amount)fromaccounta,
cardbwherea.card_no=b.card_noanda.
account_no=b.account_no(<1秒)

剖析:
在第一个毗连前提下,最好查询计划是将account作外层表,card作内层表,使用card上的索引,其I/O次数可由以下公式预算为:

外层表account上的22541页+(外层表account的191122行*内层表card上对应外层表第一行所要查找的3页)=595907次I/O

在第二个毗连前提下,最好查询计划是将card作外层表,account作内层表,使用account上的索引,其I/O次数可由以下公式预算为:

外层表card上的1944页+(外层表card的7896行*内层表account上对应外层表每行所要查找的4页)=33528次I/O

可见,只要充份的毗连前提,真实的最好计划才会被实行。

总结:

1.多表操纵在被实践实行前,查询优化器会依据毗连前提,列出几组大概的毗连计划并从中找出体系开支最小的最好计划。毗连前提要充份思索带有索引的表、行数多的表;表里表的选择可由公式:外层表中的婚配行数*内层表中每次查找的次数断定,乘积最小为最好计划。

2.检察实行计划的办法--用setshowplanon,翻开showplan选项,就能够看到毗连按次、利用何种索引的信息;想看更具体的信息,需用sa脚色实行dbcc(3604,310,302)。

3、不成优化的where子句
1.例:以下SQL前提语句中的列都建有得当的索引,但实行速率却十分慢:

select*fromrecordwhere
substring(card_no,1,4)=5378(13秒)
select*fromrecordwhere
amount/30<1000(11秒)
select*fromrecordwhere
convert(char(10),date,112)=19991201(10秒)

剖析:
where子句中对列的任何操纵了局都是在SQL运转时逐列盘算失掉的,因而它不能不举行表搜刮,而没有利用该列下面的索引;假如这些了局在查询编译时就可以失掉,那末就能够被SQL优化器优化,利用索引,制止表搜刮,因而将SQL重写成上面如许:

select*fromrecordwherecard_nolike
5378%(<1秒)
select*fromrecordwhereamount
<1000*30(<1秒)
select*fromrecordwheredate=1999/12/01
(<1秒)

你会发明SQL分明快起来!

2.例:表stuff有200000行,id_no上有非聚集索引,请看上面这个SQL:

selectcount(*)fromstuffwhereid_noin(0,1)
(23秒)

剖析:
where前提中的in在逻辑上相称于or,以是语法剖析器会将in(0,1)转化为id_no=0orid_no=1来实行。我们希冀它会依据每一个or子句分离查找,再将了局相加,如许能够使用id_no上的索引;但实践上(依据showplan),它却接纳了"OR战略",即先掏出满意每一个or子句的行,存进一时数据库的事情表中,再创建独一索引以往失落反复行,最初从这个一时表上钩算了局。因而,实践历程没有益用id_no上索引,而且完成工夫还要受tempdb数据库功能的影响。

理论证实,表的行数越多,事情表的功能就越差,当stuff有620000行时,实行工夫竟到达220秒!还不如将or子句分隔:

selectcount(*)fromstuffwhereid_no=0
selectcount(*)fromstuffwhereid_no=1

失掉两个了局,再作一次加法合算。由于每句都利用了索引,实行工夫只要3秒,在620000行下,工夫也只要4秒。大概,用更好的办法,写一个复杂的存储历程:
createproccount_stuffas
declare@aint
declare@bint
declare@cint
declare@dchar(10)
begin
select@a=count(*)fromstuffwhereid_no=0
select@b=count(*)fromstuffwhereid_no=1
end
select@c=@a+@b
select@d=convert(char(10),@c)
print@d

间接算出了局,实行工夫同下面一样快!
总结:

可见,所谓优化即where子句使用了索引,不成优化即产生了表扫描或分外开支。

1.任何对列的操纵都将招致表扫描,它包含数据库函数、盘算表达式等等,查询时要尽量将操纵移至等号右侧。

2.in、or子句常会利用事情表,使索引生效;假如不发生大批反复值,能够思索把子句拆开;拆开的子句中应当包括索引。

3.要擅长利用存储历程,它使SQL变得加倍天真和高效。

从以上这些例子能够看出,SQL优化的本色就是在了局准确的条件下,用优化器能够辨认的语句,充份使用索引,削减表扫描的I/O次数,只管制止表搜刮的产生。实在SQL的功能优化是一个庞大的历程,上述这些只是在使用条理的一种表现,深切研讨还会触及数据库层的资本设置、收集层的流量把持和操纵体系层的整体计划。


BlackHole黑洞引擎,写入的任何数据都会消失,一般用于记录binlog做复制的中继
沙发
发表于 2015-1-19 15:07:07 | 只看该作者
微软对CLR作了大篇幅的宣传,这是因为数据库产品终于融入.net体系中。最开始我们也是狂喜,感觉对象数据库的一些概念可以实现了。
变相怪杰 该用户已被删除
板凳
发表于 2015-1-24 12:56:20 | 只看该作者
理解了存储结构,再阅读下性能优化的章节基本上会对sqlserver有个清晰地认识
爱飞 该用户已被删除
地板
发表于 2015-2-1 14:06:17 | 只看该作者
SP4包括用于以下SQLServer2000组件的程序包:Database组件(下载文件:SQL2000-KB884525-SP4-x86.EXE)更新SQLServer2000的32位Database组件,包括数据库引擎、复制、客户端连接组件及工具。有关其他信息,请参阅ReadmeSql2k32Sp4.htm。AnalysisServices组件(下载文件:SQL2000.AS-KB884525-SP4-x86.EXE)更新SQLServer2000的32位AnalysisServices。
兰色精灵 该用户已被删除
5#
发表于 2015-2-7 06:28:48 | 只看该作者
对于微软系列的东西除了一遍遍尝试还真没有太好的办法
简单生活 该用户已被删除
6#
发表于 2015-2-20 20:56:30 | 只看该作者
如果我们从集合论(关系代数)的角度来看,一张数据库的表就是一组数据元的关系,而每个SQL语句会改变一种或数种关系,从而产生出新的数据元的关系(即产生新的表)。
灵魂腐蚀 该用户已被删除
7#
发表于 2015-3-6 18:51:01 | 只看该作者
如果你是从“学习某一种数据库应用软件,从而获得应聘的资本和工作机会”的角度来问的话。
admin 该用户已被删除
8#
发表于 2015-3-20 14:21:21 | 只看该作者
理解了存储结构,再阅读下性能优化的章节基本上会对sqlserver有个清晰地认识
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-12-23 00:33

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表