(1)like模糊查询
对于like ‘%...%’(全模糊)、左模糊like‘%...’。这样的条件,无法使用索引
解决办法:尽量不用模糊查询,可以用右模糊,可以走索引,即like ‘…%’
(2)询条件中is null、is not null
应尽量避免在where 子句中对字段进行null 值判断,会走全表:
select id from t where num is null
解决办法:对于is null,可以建立组合索引,nvl(字段,0),对表和索引analyse后,is null查询时可以重新启用索引查找,但是效率还不是值得肯定;is not null 时永远不会使用索引
(3)查询条件中使用了不等于操作符(<>、!=)
解决方法:通过把不等于操作符改成or,可以使用索引
(4)组合索引使用不当
查询条件中没有前导列,导致索引不起作用,如没有job前导列:
create index skip1 on emp5(job,empno);
select count(*) from emp5 where empno=7900; //全表扫描
使用组合索引时,在排序时应按照组合索引中各列顺序进行排序(即使只有一个列需要排序),否则性能较差:
create index skip1 on emp5(job,empno,date);
select job,empno from emp5 where job=’manager’and empno=’10’ ORDER BY date desc; //性能较差
select job,empno from emp5 where job=’manager’and empno=’10’ ORDER BY job,empno,date desc; //使用组合索引
(5)OR
语句连接的条件中包含的列(左右)没有全部建立索引
例如:where子句中比较的两个条件,一个有索引,一个没索引,使用or则会引起全表扫描。例如:where A=1 or B=2,A上有索引,B上没索引,则比较B=2时会重新开始全表扫描
where条件下OR的改造:
如:select id from t where num=10 or num=20;
改造为:select id from t where num=10 union all select id from t where num=20;
(6)in 和not in 导致全表
如:select id from t where num in(1,2,3);
(等效于select * from user where userId = 1 or userId = 2 or userId = 3;)
改造1:对于连续的数值,能用between 就不要用in :select id from t where num between 1 and 3;
改造2:用exists代替in:
(in查询的子条件返回结果必须只有一个字段,例如:select * from user where userId in (select id from B);
而不能是:select * from user where userId in (select id, age from B); 而exists就没有这个限制)
(7)在where字句对字段进行表达式或者函数操作
如:
select id from t where substring(name,1,3)='abc'; --name
select id from t where datediff(day,createdate,'2005-11-30')=0; --‘2005-11-30’
改造为:
select id from t where name like 'abc%'
select id from t where createdate>='2005-11-30' and createdate<'2005-12-1'
上一篇:explain的使用
若对你有帮助,欢迎关注!!点赞!!评论!!