索引的应用有一定规律可寻,但其和实际情况的结合更紧密,只有在具体的应用环境里,才能体会到索引应用的奥妙,现录各种索引应用案例于此,供体会。
<!-- google_ad_client = "pub-1532173932791927"; google_ad_width = 125; google_ad_height = 125; google_ad_format = "125x125_as_rimg"; google_cpa_choice = "CAAQ5fifnAIaCE93wD3uKY5rKN2_93M"; google_ad_channel = ""; //-->
案例一 群集索引的应用>表record有620000行,有字段date, amount, place等
1. 在date上建有一非个群集索引 select count(*) from record where date > ‘19991201′ and date 2000 (25秒)
select date,sum(amount) from record group by date (55秒)
select count(*) from record where date > ‘19990901′ and place in (’BJ’,'SH’) (27秒)
分析:
date上有大量的重复值,在非群集索引下,数据在物理上随机存放在数据页上,在范围查找时,必须执行一次表扫描才能找到这一范围内的全部行。 可以在date上的一个群集索引,在群集索引下,数据在物理上按顺序在数据页上,重复值也排列在一起,因而在范围查找时,可以先找到这个范围的起末点,且只在这个范围内扫描数据页,避免了大范围扫描,提高了查询速度。
2. 在date,place,amount上的组合索引
select count(*) from record where date > ‘19991201′ and date 2000( select date,sum(amount) from record group by date (11秒)
select count(*) from record where date > ‘19990901′ and place in (’BJ’,'SH’)( 分析: 这是一个合理的组合索引。它将date作为前导列,使每个SQL都可以利用索引,并且在第一和第三个SQL中形成了索引覆盖,因而性能达到了最优。 注意,为什么要以date作为前导列呢?因为date列在条件中应用做广泛,3条查询中都用到date做条件,所以要用date做前导列,对大多数查询都有用。相应的,在where条件中,也要把条件date放在第1位。反之,如果用amount做前导列,则所有3条SQL都用不到索引。
案例二 避免列函数使索引失效>
列SQL条件语句中的列都建有恰当的索引,但执行速度却非常慢:
select * from record where
substring(card_no,1,4)=’5378′(13秒)
select * from record where
amount/30 select * from record where
convert(char(10),date,112)=’19991201′(10秒)
分析:
where子句中对列的任何操作结果都是在SQL运行时逐列计算得到的,因此它不得不进行表搜索,而没有使用该列上面的索引;如果这些结果在查询编译时就能得到,那么就可以被SQL优化器优化,使用索引,避免表搜索,因此将SQL重写成下面这样:
select * from record where card_no like ’5378%’( select * from record where amount
select * from record where date= ‘1999/12/01′
( 你会发现SQL明显快起来!
案例三 in和or不能使用索引时如何解决>
表stuff有200000行,id_no上有非群集索引,请看下面这个SQL:
select count(*) from stuff where id_no in(’0′,’1′)
(23秒)
分析:
where条件中的’in’在逻辑上相当于’or’,所以语法分析器会将in (’0′,’1′)转化为id_no =’0′ or id_no=’1′来执行。我们期望它会根据每个or子句分别查找,再将结果相加,这样可以利用id_no上的索引;但实际上(根据showplan),它却采用了”OR策略”,即先取出满足每个or子句的行,存入临时数据库的工作表中,再建立唯一索引以去掉重复行,最后从这个临时表中计算结果。因此,实际过程没有利用id_no上索引,并且完成时间还要受tempdb数据库性能的影响。
实践证明,表的行数越多,工作表的性能就越差,当stuff有620000行时,执行时间竟达到220秒!还不如将or子句分开:
select count(*) from stuff where id_no=’0′
select count(*) from stuff where id_no=’1′
得到两个结果,再作一次加法合算。因为每句都使用了索引,执行时间只有3秒,在620000行下,时间也只有4秒。或者,用更好的方法,写一个简单的存储过程:
create proc count_stuff as
declare @a int
declare @b int
declare @c int
declare @d char(10)
begin
select @a=count(*) from stuff where id_no=’0′
select @b=count(*) from stuff where id_no=’1′
end
select @c=@a+@b
select @d=convert(char(10),@c)
print @d
直接算出结果,执行时间同上面一样快!
所谓优化即where子句利用了索引,不可优化即发生了表扫描或额外开销。
1.任何对列的操作都将导致表扫描,它包括数据库函数、计算表达式等等,查询时要尽可能将操作移至等号右边。
2.in、or子句常会使用工作表,使索引失效;如果不产生大量重复值,可以考虑把子句拆开;拆开的子句中应该包含索引。
3.要善于使用存储过程,它使SQL变得更加灵活和高效。
案例四
表card有7896行,在card_no上有一个非聚集索引,表account有191122行,在 account_no上有一个非聚集索引,试看在不同的表连接条件下,两个SQL的执行情况:
select sum(a.amount) from account a,
card b where a.card_no = b.card_no(20秒)
将SQL改为:
select sum(a.amount) from account a,
card b where a.card_no = b.card_no and a.
account_no=b.account_no(
分析:
在第一个连接条件下,最佳查询方案是将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.查看执行方案的方法– 用set showplanon,打开showplan选项,就可以看到连接顺序、使用何种索引的信息;想看更详细的信息,需用sa角色执行dbcc(3604,310,302)。
相关推荐
├─第二篇 诊断案例篇 │ 01.ASM案例分析与诊断 │ 02.监听故障的诊断与分析 │ 03.ORA系列错误与诊断 │ 04.ORA-01200错误裸设备恢复 │ 05.Oracle数据库无响应故障的处理 │ 06.RAC环境诊断案例一则 ├─第三篇 ...
第4章 规划Oracle应用程序——方法、风险和标准 第Ⅱ部分 SQL和SQL*Plus 第5章 SQL中的基本语法 第6章 基本的SQL*Plus报表及命令 第7章 文本信息的收集与修改 第8章 正则表达式搜索 第9章 数值处理 第10章 日期:...
上篇 开启惊喜之门——带意识地学Oracle 第1章意识,少做事从学习开始 2 1.1 选择先学什么颇有学问 2 1.1.1 梁老师课堂爆笑开场 2 1.1.2 看似跑题的手机分类 4 1.1.3 学什么先了解做什么 5 1.2 善于规划分类才有...
简单来说是本身可视为电子化的文件柜——存储电子文件的处所,用户可以对文件中的数据运行新增、截取、更新、删除等操作。 常见的数据模型 1. 层次结构模型: 层次结构模型实质上是一种有根结点的定向有序树,IMS...
第10章 且慢,其他索引应用让SQL飞 270 10.1 其他索引的总体概述 270 10.1.1 位图索引 271 10.1.2 函数索引 271 10.1.3 反向键索引 272 10.1.4 全文索引 272 10.2 走进其他索引的世界 272 10.2.1 位图索引 ...
1.4.5. 步骤#5: 创建测试案例 13 1.4.6. 步骤#6: 找一个良师 14 1.4.7. 步骤#7: 参加本地用户群 14 1.5. 我如何能够从一名DBA初学者变为一个具有中级水平的DBA? 14 1.5.1. 步骤#1: 学习操作系统和你的服务器硬件 14...
2.深入浅出Oracle:DBA入门、进阶与诊断案例 ——盖国强 3.Oracle 书籍《Oracle 11g 实用教程》 引言 ............................................................................................................
(3)、介绍用于工程设计、选线、规划、工程选址及铁路与公路交通三维仿真的应用软件的关键技术—————国际最优秀的Creator/Vega软件操作与制作应用上机(机房),将介绍如何利用可免费获得的OPENGL函数库与控件的...
第13章 网络留言板续——Oracle数据库 第14章 AJAX技术JQuery框架的经典应用 第15章 在线文件上传和下载(Struts 2.X+FileUpload) 第16章 网上投票系统(Struts2.X+JFreeChat) 第17章 商业银行网上账户管理系统...
第13章 网络留言板续——Oracle数据库 第14章 AJAX技术JQuery框架的经典应用 第15章 在线文件上传和下载(Struts 2.X+FileUpload) 第16章 网上投票系统(Struts2.X+JFreeChat) 第17章 商业银行网上账户管理系统...
第13章 网络留言板续——Oracle数据库 第14章 AJAX技术JQuery框架的经典应用 第15章 在线文件上传和下载(Struts 2.X+FileUpload) 第16章 网上投票系统(Struts2.X+JFreeChat) 第17章 商业银行网上账户管理系统...
17.3 Session应用实例——登录验证 286 17.3.1 数据库设计 286 17.3.2 HTML表单的设计 287 17.3.3 验证页面的编写 287 17.3.4 欢迎页面的编写 288 17.3.5 注销页面的编写 288 17.3.6 代码的运行 289 17.3.7 代码的...
本书特色:主要介绍SQL的语法规则及在实际开发中的应用,并且对SQL在MySQL、MS SQL Server、Oracle和DB2中的差异进行了分析;详细讲解数据库对增、删、改、查等SQL的支持并给出了相应的SQL应用案例;透彻分析函数...
第13章 网络留言板续——Oracle数据库 第14章 AJAX技术JQuery框架的经典应用 第15章 在线文件上传和下载(Struts 2.X+FileUpload) 第16章 网上投票系统(Struts2.X+JFreeChat) 第17章 商业银行网上账户管理系统...
和oracle和相似,在oracle中支持的表类型几乎在dm中都存在,但不同的是,oracle中默认是堆表,而在dm中默认是索引组织表,当然这个可以在初始化实例的时候修改。此外,dm中还支持临时表,分区表,外部表等。 如何去...
海量案例完美结合,线上线下拓展延伸。 内容简介 有人就有江湖,有江湖就有IT系统,有IT系统就有数据库,有数据库就有SQL,SQL应用可一字概括:“广”。加之其简单易学,SQL实现也可一字概括:“乐”。 然而,SQL...
动态调用对象的属性和方法——性能和灵活性兼备的方法 消除由try/catch语句带来的warning 微软的应试题完整版(附答案) 一个时间转换的问题,顺便谈谈搜索技巧 .net中的正则表达式使用高级技巧 (一) C#静态成员和...
1.2.9 数据库的语言——SQL 1.2.10 DBA与程序员 第2章 数据表的创建和管理 2.1 数据类型 2.1.1 整数类型 2.1.2 数值类型 2.1.3 字符相关类型 2.1.4 日期时间类型 2.1.5 二进制类型 2.2 通过SQL...