数据库索引和SQL语句使用经验

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

数据库索引和SQL语句使⽤经验
1、如果检索数据量超过30%的表中记录数,使⽤索引将没有显著的效率提⾼
2、在特定情况下,使⽤索引也许会⽐全表扫描慢,但这是同⼀个数量级上的差距;⽽通常情况下,使⽤索引⽐全表扫描要快⼏倍乃⾄⼏千倍!
⽤索引提⾼效率
索引是表的⼀个概念部分,⽤来提⾼检索数据的效率。

实际上,ORACLE使⽤了⼀个复杂的⾃平衡B-tree结构。

通常,通过索引查询数据⽐全表扫描要快。

当ORACLE找出执⾏查询和Update语句的最佳路径时,ORACLE优化器将使⽤索引。

同样在联结多个表时使⽤索引也可以提⾼效率。

另⼀个使⽤索引的好处是,它提供了主键(primary key)的唯⼀性验证。

除了那些LONG或LONG RAW数据类型, 你可以索引⼏乎所有的列。

通常, 在⼤型表中使⽤索引特别有效。

当然,在扫描⼩表时,使⽤索引同样能提⾼效率。

虽然使⽤索引能得到查询效率的提⾼,但是我们也必须注意到它的代价。

索引需要空间来存储,也需要定期维护,每当有记录在表中增减或索引列被修改时,索引本⾝也会被修改。

这意味着每条记录的INSERT , DELETE , UPDATE将为此多付出4 , 5 次的磁盘I/O。

因为索引需要额外的存储空间和处理,那些不必要的索引反⽽会使查询反应时间变慢,所以索引不能盲⽬的建⽴。

建⽴索引
表的主键、外键必须有索引;
经常与其他表进⾏连接的表,在连接字段上应该建⽴索引,多表进⾏多字段连接,建议适当建⽴复合索引;
索引应该建⽴在查询条件中进⾏⽐较的字段上,⽽不是建⽴在我们要找出来并且显⽰的字段上;
在条件表达式中经常⽤到的不同值较多的列上建⽴检索,在不同值少的列上不要建⽴索引;<段落>⽐如在雇员表的“性别”列上只
有“男”与“⼥”两个不同值,因此就⽆必要建⽴索引。

如果建⽴索引不但不会提⾼查询效率,反⽽会严重降低更新速度。

<段落>组合索引要尽量使关键查询形成索引覆盖,其前导列⼀定是使⽤最频繁的列。

索引失效
1、IN、OR⼦句常会使⽤⼯作表
使索引失效。

如果不产⽣⼤量重复值,可以考虑把⼦句拆开。

拆开的⼦句中应该包含索引。

例⼦如下:<段落>如果在fields1和fields2上同时建⽴了索引,fields1为主索引以下sql会⽤到索引 select * from tablename1 where fields1=’value1’ and fields2=’value2’ 以下sql不会⽤到索引select * from tablename1 where fields1=’value1’ or fields2=’value2’
2、使⽤IS NULL 或IS NOT NULL
使⽤IS NULL 或IS NOT NULL同样会限制索引的使⽤。

因为NULL值并没有被索引定义。

在SQL语句中使⽤NULL会有很多的⿇烦。

因此建议开发⼈员在建表时,把需要索引的列设成NOT NULL。

如果被索引的列在某些⾏中存在NULL值,就不会使⽤这个索引。

也可以使⽤特定的值来代替NULL。

请避免在索引中使⽤任何可以为空的列,oracle将⽆法使⽤该索引。

对于单列索引,如果列包含空值,索引中将不存在此记录;
对于复合索引,如果每个列都为空,索引中同样不存在此记录。

如果⾄少有⼀个列不为空,则记录存在于索引中
因为空值不存在于索引列中,所以where⼦句中对索引列进⾏空值⽐较将使oracle停⽤该索引
(索引失效)
select … from department where dept_code is not null
3、条件字段使⽤函数和表达式
如果不使⽤基于函数的索引,那么在SQL语句的WHERE⼦句中对存在索引的列使⽤函数时,会使优化器忽略掉这些索引。

下⾯的查询不会使⽤索引(只要它不是基于函数的索引)
select empno,ename,deptno from emp where trunc(hiredate)='01-MAY-81';
把上⾯的语句改成下⾯的语句,这样就可以通过索引进⾏查找。

select empno, ename, deptno from emp where hiredate < (to_date('01-MAY-81') + 0.9999);
请务必注意,检索中不要对索引列进⾏处理,如:trim,to_date,类型转换等操作,破坏索引,使⽤全表扫描,影响sql执⾏效率<段落>4、避免在索引列上使⽤计算
假如索引列是函数的⼀部分,优化器将不使⽤索引⽽使⽤全表扫描。

低效: SELECT … FROM DEPT WHERE SAL * 12 > 25000;
⾼效: SELECT … FROM DEPT WHERE SAL > 25000/12;<段落>5、⽐较不匹配的数据类型
⽐较不匹配的数据类型也是⽐较难于发现的性能问题之⼀。

注意下⾯查询的例⼦,account_number是⼀个VARCHAR2类型,在
account_number字段上有索引。

下⾯的语句将执⾏全表扫描。

select bank_name, address, city, state, zip from banks where account_number = 990354;
Oracle可以⾃动把where⼦句变成to_number(account_number)=990354,这样就限制了索引的使⽤,改成下⾯的查询就可以使⽤索引:select bank_name, address, city, state, zip from banks where account_number = '990354';
特别注意:不匹配的数据类型之间⽐较会让Oracle⾃动限制索引的使⽤,即便对这个查询执⾏Explain Plan也不能让您明⽩为什么做了⼀
次“全表扫描”。

6、带通配符(%)的like语句
要求在职⼯表中查询名字中包含cliton的⼈。

可以采⽤如下的查询SQL语句:
select * from employee where last_name like '%cliton%';
这⾥由于通配符(%)在搜寻词⾸出现,所以Oracle系统不使⽤last_name的索引。

在很多情况下可能⽆法避免这种情况,但是⼀定要⼼中有底,通配符如此使⽤会降低查询速度。

然⽽当通配符出现在字符串其他位置时,优化器就能利⽤索引。

在下⾯的查询中索引得到了使⽤: select * from employee where last_name like 'c%';
7、Order by语句
ORDER BY语句决定了Oracle如何将返回的查询结果排序。

Order by语句对要排序的列没有什么特别的限制,也可以将函数加⼊列中(象联接或者附加等)。

任何在Order by语句的⾮索引项或者有计算表达式都将降低查询速度。

仔细检查order by语句以找出⾮索引项或者表达式,它们会降低性能。

解决这个问题的办法就是重写order by语句以使⽤索引,也可以为所使⽤的列建⽴另外⼀个索引,同时应绝对避免在order by⼦句中使⽤表达式。

8、⼤于或⼩于操作符
⼤于或⼩于操作符⼀般情况下是不⽤调整的,因为它有索引就会采⽤索引查找,但有的情况下可以对它进⾏优化。

如⼀个表有100万记录,⼀个数值型字段A,30万记录的A=0,30万记录的A=1,39万记录的A=2,1万记录的A=3。

那么执⾏A>2与A>=3的效果就有很⼤的区别了,
因为A>2时ORACLE会先找出为2的记录索引再进⾏⽐较,⽽A>=3时ORACLE则直接找到=3的记录索引。

相关文档
最新文档