1、IN操作符

用IN操作符写出来的SQL直观简单、易于理解。但是在where条件中使用IN操作符是低效的。例如下面这条查询语句:

SELECT *

FROM tab_a

WHERE id IN(

SELECT a_id FROM tab_b);

你认为它会怎么执行呢?先从tab_a表中遍历数据,然后拿每行数据的id字段去tab_b表中去查找,只要找到就把这行纳入查询结果。

大错特错!事实上,RDBMS会先执行第4行的子查询,把查出的数据保存到一张临时表中,再执行主查询,利用临时表中的数据去核对主查询的where条件是否成立。

这是IN操作符低效的主要原因,因为临时表是没有索引的,要核对当前数据行的id值在临时表中是否出现,必须遍历临时表。也就是说tab_b表中即使对a_id字段建了索引也是没有用的。

推荐方案是使用表连接:

SELECT tab_a.*

FROM  tab_a INNER JOIN tab_b

ON tab_a.id=tab_b.id;

或者使用EXISTS操作符:

SELECT *

FROM tab_a

WHERE EXISTS

SELECT *

FROM tab_b

WHERE tab_a.id=tab_b.a_id;

注意,NOT IN和IN存在类似的问题,也是无法利用表上的索引。

2、IS NULL和IS NOT NULL

值得一提的是,数据库是不索引空值的,也就是说即便你在一个字段上建立的索引,当针对这个字段进行查询时,还是需要遍历整张表。

3、LIKE

LIKE操作符用于模糊查询,通过使用通配符可以进行非常灵活的查询,但是如果运用不当则会造成索引失效从而影响性能。

例如,LIKE '%abc%'这种两头都带通配符的查询不会使用到索引,而LIKE 'abc%'会使用到索引来缩小查询范围,从而提高性能。

4、where条件中的函数

where条件中如果出现函数则索引会失效,例如下面的查询语句:

SELECT *

FROM tab

WHERE substring(name,1,3)='abc';

   where条件中队name字段进行了取子串的函数转换,这样,即便name字段上建了索引,这个索引在查询的时候也不会被用到。

对于这种情况,即便是下面这条语句,也比上面的那条要强得多:

SELECT *

FROM tab

WHERE NAME LIKE 'abc%'

5、where条件中表内字段相互交杂

   在where条件中,如果出现本表内的字段相互连接或比较,则字段上的索引是无法生效的,比如下面的语句:

SELECT *

FROM tab

WHERE name||gener = 'abcF'

   name和gender上即使有索引,也不起作用。

下面的语句也是类似的情况: 

SELECT *

FROM tab

WHERE age>score

age字段和score字段都是tab表的字段,相互比较,不会引用索引。

SQL查询:『索引失效问题』的更多相关文章

  1. mybatis的sql语句导致索引失效,使得查询超时

    mybaitis书写sql需要特别注意where条件中的语句,否则将会导致索引失效,使得查询总是超时.如下语句会出现导致索引失效的情况: with test1 as (select count(C_F ...

  2. SQL优化避免索引失效

    Oracle 索引的目标是避免全表扫描,提高查询效率,但有些时候却适得其反.例如一张表中有上百万条数据,对某个字段加了索引,但是查询时性能并没有什么提高,这可 能是 oracle 索引失效造成的.or ...

  3. MySQL中为避免索引失效所需注意的问题

    一.索引介绍 二.索引的优势与劣势 1.优势 类似于书籍的目录索引,提高数据检索的效率,降低数据库的IO成本. 通过索引列对数据进行排序,降低数据排序的成本,降低CPU的消耗. 2.劣势 实际上索引也 ...

  4. SQL SERVER 中is null 和 is not null 将会导致索引失效吗?

    其实本来这个问题没有什么好说的,今天优化的时候遇到一个SQL语句,因为比较有意思,所以我截取.简化了SQL语句,演示给大家看,如下所示 declare @bamboo_Code varchar(3); ...

  5. 索引 使用use index优化sql查询

    好博客:MySQL http://webnoties.blog.163.com/blog/#m=0&t=1&c=fks_08407108108708107008508508609508 ...

  6. sql查询调优之where条件排序字段以及limit使用索引的奥秘

       奇怪的慢sql 我们先来看2条sql 第一条: select * from acct_trans_log WHERE  acct_id = 1000000000009000757 order b ...

  7. sql优化策略之索引失效情况二

    详见: http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp63   接第一篇索引失效分析:http://grefr.iteye.co ...

  8. SQL优化 MySQL版 - 避免索引失效原则(二)

    避免索引失效原则(二) 注:继上一篇文章继续讲解: 避免索引失效原则(一)https://www.cnblogs.com/StanleyBlogs/p/10482048.html#4195062 作者 ...

  9. SQL优化 MySQL版 - 避免索引失效原则(一)

    避免索引失效原则(一) 精力有限,剩余的失效原则将会在 <避免索引失效原则(二)>中连载出来,请谅解 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 避免索引失效的一些原 ...

随机推荐

  1. SQLite数据库入门教程

    SQLite数据库入门教程 SQLite 是一个开源的嵌入式关系数据库,实现自包容.零配置.支持事务的SQL数据库引擎. 其特点是高度便携.使用方便.结构紧凑.高效.可靠. 与其他数据库管理系统不同, ...

  2. C#中反射的使用(How to use reflect in CSharp)(1)

    最近想做一个插件式的软件给公司的监控用,初步的想法是使用C#去反射Dll,Invoke其中的方法.此文仅供开发参考,不涉及原理,98%的代码以及2%的废话. 测试Solution是这么建的(.NET ...

  3. iOS调用系统通讯录获取姓名电话号码(转)

    原文地址:http://blog.csdn.net/idoshi201109/article/details/46007125 OS调用系统通讯录获取姓名电话号码 (iOS 8.0 Xcode6.3可 ...

  4. powershell.exe直接运行命令

    powershell.exe -Command "& { ('time={0},user={1}' -f (get-date),(whoami)) | Out-File " ...

  5. Android 如何修改默认的searchable items。

    前言          欢迎大家我分享和推荐好用的代码段~~ 声明          欢迎转载,但请保留文章原始出处:          CSDN:http://www.csdn.net        ...

  6. httpclient模拟浏览器訪问站点

    HttpClient 是 Apache Jakarta Common 下的子项目.能够用来提供高效的.最新的.功能丰富的支持 HTTP 协议的client编程工具包.而且它支持 HTTP 协议最新的版 ...

  7. DTCC2016

    http://pan.baidu.com/share/home?uk=4043574767#category/type=0

  8. 分布式应用处理方式 - Remoting

    分布式应用程序 所谓分布式计算是一门计算机科学,它研究如何把一个需要非常巨大的计算能力才能解决的问题分成许多小的部分,然后把这些部分分配给许多计算机进行处理,最后把这些计算结果综合起来得到最终的结果. ...

  9. C语言---翻译过程

    c的实现中包括两种环境: 1.翻译环境(translation environment):源程序---->机器指令 2.执行环境(execution environment):执行机器指令 这两 ...

  10. 关于Integer类中parseInt()和valueOf()方法的区别以及int和String类性的转换.以及String类valueOf()方法

    Integer类中的. 关于parseInt()方法的API文档.  返回的是int类型的 关于valueOf()方法的API文档 返回的是Integer类型的. 关于intValue()方法的API ...