基于索引的SQL语句优化之降龙十八掌.doc
《基于索引的SQL语句优化之降龙十八掌.doc》由会员分享,可在线阅读,更多相关《基于索引的SQL语句优化之降龙十八掌.doc(10页珍藏版)》请在三一办公上搜索。
1、基于索引的SQL语句优化之降龙十八掌1前言22总纲23降龙十八掌3第一掌防止对列的操作3第二掌防止不必要的类型转换4第三掌增加查询的围限制4第四掌尽量去掉IN、OR4第五掌尽量去掉 5第六掌去掉Where子句中的IS NULL和IS NOT NULL5第七掌索引提高数据分布不均匀时查询效率5第八掌利用HINT强制指定索引6第九掌屏蔽无用索引6第十掌分解复杂查询,用常量代替变量7第十一掌 like子句尽量前端匹配7第十二掌用Case语句合并多重扫描7第十三掌使用nls_date_format8第十四掌使用基于函数的索引8第十五掌基于函数的索引要求等式匹配9第十六掌使用分区索引9第十七掌使用位图索
2、引9第十八掌决定使用全表扫描还是使用索引94总结101 前言客服业务受到SQL语句的影响非常大,在规模比拟大的局点,往往因为一个小的SQL语句不够优化,导致数据库性能急剧下降,小型机idle所剩无几,应用效劳器断连、超时,严重影响业务的正常运行。因此,称低效的SQL语句为客服业务的恶龙并不过分。数据库的优化方法有很多种,在应用层来说,主要是基于索引的优化。本次秘笈根据实际的工作经历,在研发原来已有的方法的根底上,进展了一些扩大,总结了基于索引的SQL语句优化的降龙十八掌,希望有一天你能用其中一掌来驯服客服业务中横行的恶龙。2 总纲l 建立必要的索引这次传授的降龙十八掌,总纲只有一句话:建立必要
3、的索引,这就是后面降龙十八掌的功根底。这一点看似容易实际却很难。难就难在如何判断哪些索引是必要的,哪些又是不必要的。判断的最终标准是看这些索引是否对我们的数据库性能有所帮助。具体到方法上,就必须熟悉数据库应用程序中的所有SQL语句,从中统计出常用的可能对性能有影响的局部SQL,分析、归纳出作为Where条件子句的字段及其组合方式;在这一根底上可以初步判断出哪些表的哪些字段应该建立索引。其次,必须熟悉应用程序。必须了解哪些表是数据操作频繁的表;哪些表经常与其他表进展连接;哪些表中的数据量可能很大;对于数据量大的表,其中各个字段的数据分布情况如何;等等。对于满足以上条件的这些表,必须重点关注,因为
4、在这些表上的索引,将对SQL语句的性能产生举足轻重的影响。不过下面还是总结了一下降龙十八掌功的入门根底,建立索引常用的规则如下:1、表的主键、外键必须有索引;2、数据量超过300的表应该有索引;3、经常与其他表进展连接的表,在连接字段上应该建立索引;4、经常出现在Where子句中的字段,特别是大表的字段,应该建立索引;5、索引应该建在选择性高的字段上;6、索引应该建在小字段上,对于大的文本字段甚至超长字段,不要建索引;7、复合索引的建立需要进展仔细分析;尽量考虑用单字段索引代替: A、正确选择复合索引中的主列字段,一般是选择性较好的字段; B、复合索引的几个字段是否经常同时以AND方式出现在W
5、here子句中?单字段查询是否极少甚至没有?如果是,则可以建立复合索引;否则考虑单字段索引; C、如果复合索引中包含的字段经常单独出现在Where子句中,则分解为多个单字段索引; D、如果复合索引所包含的字段超过3个,则仔细考虑其必要性,考虑减少复合的字段;E、如果既有单字段索引,又有这几个字段上的复合索引,一般可以删除复合索引;8、频繁进展数据操作的表,不要建立太多的索引;9、删除无用的索引,防止对执行方案造成负面影响;以上是一些普遍的建立索引时的判断依据。一言以蔽之,索引的建立必须慎重,对每个索引的必要性都应该经过仔细分析,要有建立的依据。因为太多的索引与不充分、不正确的索引对性能都毫无益
6、处:在表上建立的每个索引都会增加存储开销,索引对于插入、删除、更新操作也会增加处理上的开销。另外,过多的复合索引,在有单字段索引的情况下,一般都是没有存在价值的;相反,还会降低数据增加删除时的性能,特别是对频繁更新的表来说,负面影响更大。3 降龙十八掌第一掌 防止对列的操作任何对列的操作都可能导致全表扫描,这里所谓的操作包括数据库函数、计算表达式等等,查询时要尽可能将操作移至等式的右边,甚至去掉函数。例1:以下SQL条件语句中的列都建有恰当的索引,但30万行数据情况下执行速度却非常慢:select * from record where substrb(CardNo,1,4)=5378(13秒
7、) select * from record where amount/30 100011秒select * from record where to_char(ActionTime,yyyymmdd)=1999120110秒由于where子句中对列的任何操作结果都是在SQL运行时逐行计算得到的,因此它不得不进展表扫描,而没有使用该列上面的索引;如果这些结果在查询编译时就能得到,则就可以被SQL优化器优化,使用索引,防止表扫描,因此将SQL重写如下:select * from record where CardNo like 5378% 1秒select * from record where
8、 amount 1000*30 1秒select * from record where ActionTime= to_date (19991201 ,yyyymmdd)10,应该写为: select col1,col2 from tab1 where col110。第三掌 增加查询的围限制增加查询的围限制,防止全围的搜索。例3:以下查询表record 中时间ActionTime小于2001年3月1日的数据:select * from record where ActionTime to_date (20010301 ,yyyymm)查询方案说明,上面的查询对表进展全表扫描,如果我们知道表中的
9、最早的数据为2001年1月1日,则,可以增加一个最小时间,使查询在一个完整的围之。修改如下: select * from record where ActionTime to_date (20010101 ,yyyymm)后一种SQL语句将利用上ActionTime字段上的索引,从而提高查询效率。把20010301换成一个变量,根据取值的机率,可以有一半以上的时机提高效率。同理,对于大于*个值的查询,如果知道当前可能的最大值,也可以在Where子句中加上“AND 列名 MA*(最大值)。第四掌 尽量去掉IN、OR含有IN、OR的Where子句常会使用工作表,使索引失效;如果不产生大量重复值,可
10、以考虑把子句拆开;拆开的子句中应该包含索引。例4:select count(*) from stuff where id_no in(0,1)23秒可以考虑将or子句分开:select count(*) from stuff where id_no=0 select count(*) from stuff where id_no=1然后再做一个简单的加法,与原来的SQL语句相比,查询速度更快。第五掌 尽量去掉 尽量去掉 ,防止全表扫描,如果数据是枚举值,且取值围固定,则修改为OR方式。例5:UPDATE SERVICEINFO SET STATE=0 WHERE STATE0;以上语句由于其中
11、包含了,执行方案中用了全表扫描TABLE ACCESS FULL,没有用到state字段上的索引。实际应用中,由于业务逻辑的限制,字段state为枚举值,只能等于0,1或2,而且,值等于=1,2的很少,因此可以去掉,利用索引来提高效率。修改为:UPDATE SERVICEINFO SET STATE=0 WHERE STATE = 1 OR STATE = 2。进一步的修改可以参考第4种方法。第六掌 去掉Where子句中的IS NULL和IS NOT NULLWhere字句中的IS NULL和IS NOT NULL将不会使用索引而是进展全表搜索,因此需要通过改变查询方式,分情况讨论等方法,去掉
12、Where子句中的IS NULL和IS NOT NULL。第七掌 索引提高数据分布不均匀时查询效率索引的选择性低,但数据的值分布差异很大时,仍然可以利用索引提高效率。A、数据分布不均匀的特殊情况下,选择性不高的索引也要创立。表ServiceInfo中数据量很大,假设有一百万行,其中有一个字段DisposalCourseFlag,取值围为枚举值:0,1,2,3,4,5,6,7。按照前面说的索引建立的规则,“选择性不高的字段不应该建立索引,该字段只有8种取值,索引值的重复率很高,索引选择性明显很低,因此不建索引。然而,由于该字段上数据值的分布情况非常特殊,具体如下表:取值围1567占总数据量的百分
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 索引 SQL 语句 优化 降龙十八掌

链接地址:https://www.31ppt.com/p-1180297.html