精华内容
下载资源
问答
  • MySQL索引失效

    2021-04-27 13:10:44
    导致索引失效使用模糊查询的索引失效使用not in 或 not exists的索引失效使用is null 或 is not null 的索引失效使用函数导致的索引失效使用类型不一致的索引失效运算符导致的索引失效or引起的索引失效MySQL查询优化...

    简要

    在我们常规做数据库开发时,都会为每个表设置适合它的索引来加快数据库的搜索效率。

    但有了索引也不是说就万事大吉,所有查询都没问题。像我们使用

    但也可能因为你使用错误的SQL语句而无法使用。其中有以下几种,在使用sql查询时尽量避免。

    使用!=或<>导致索引失效

    select * from user where name <> '张三疯';
    

    使用模糊查询的索引失效

    最左侧不使用%时也会使用索引(最左匹配),否则不使用索引。

    select * from user where name like '%疯%';
    

    使用not in 或 not exists的索引失效

    select * from user where name not in ('张三疯');
    

    使用is null 或 is not null 的索引失效

    select * from user where name is not null;
    

    使用函数导致的索引失效

    select * from user where date(create_time) = '2021-04-27';
    

    使用类型不一致的索引失效

    查询条件类型与字段类型不相符时,如下边例子,字段是字符串类型条件使用数值类型。

    select * from user where name > 18;
    

    运算符导致的索引失效

    包括(+、-、*、/)都会导致索引失效

    select * from user where age + 2 = 18;
    

    or引起的索引失效

    or导致索引失效是在特定情况下,并不是所有的or都会导致索引失效,如果or连接的是一个字段,那么就不会失效,反之索引失效。

    select * from user where name = '张三疯' or age > 18;
    

    MySQL查询优化器最终选择不走索引

    即使完全符合索引生效的场景,考虑到实际数据量等原因,最终是否使用索引还要看MySQL优化器的判断。当然你也可以在sql语句中写明强制走某个索引。

    索引本身失效

    这种情况概率极低,我也只遇到过一回,确定where条件使用了索引也执行了查询,但返回的数据结果与实际不相符。未能找到原因,后来只是把这个索引删除后重建就正常了。

    展开全文
  • mysql索引失效的场景

    2021-01-04 14:34:30
    之前有看过许多类似的文章内容,提到过一些sql语句的使用不当会导致MySQL的索引失效。还有一些MySQL“军规”或者规范写明了某些sql不能这么写,否则索引失效。 绝大部分的内容笔者是认可的,不过部分举例中笔者认为...

    前言

    之前有看过许多类似的文章内容,提到过一些sql语句的使用不当会导致MySQL的索引失效。还有一些MySQL“军规”或者规范写明了某些sql不能这么写,否则索引失效。

    绝大部分的内容笔者是认可的,不过部分举例中笔者认为用词太绝对了,并没有说明其中的原由,很多人不知道为什么。所以笔者绝对再整理一遍MySQL中索引失效的常见场景,并分析其中的原由供大家参考。

    当然请记住,explain是一个好习惯!

    MySQL索引失效的常见场景

    在验证下面的场景时,请准备足够多的数据量,因为数据量少时,MySQL的优化器有时会判定全表扫描无伤大雅,就不会命中索引了。

    1. where语句中包含or时,可能会导致索引失效

    使用or并不是一定会使索引失效,你需要看or左右两边的查询列是否命中相同的索引。

    假设USER表中的user_id列有索引,age列没有索引。

    下面这条语句其实是命中索引的(据说是新版本的MySQL才可以,如果你使用的是老版本的MySQL,可以使用explain验证下)。

    1

    select * from `user` where user_id = 1 or user_id = 2;

    但是这条语句是无法命中索引的。

    1

    select * from `user` where user_id = 1 or age = 20;

    假设age列也有索引的话,依然是无法命中索引的。

    1

    select * from `user` where user_id = 1 or age = 20;

    因此才有建议说,尽量避免使用or语句,可以根据情况尽量使用union all或者in来代替,这两个语句的执行效率也比or好些。

    2. where语句中索引列使用了负向查询,可能会导致索引失效

    负向查询包括:NOT、!=、<>、!<、!>、NOT IN、NOT LIKE等。

    某“军规”中说,使用负向查询一定会索引失效,笔者查了些文章,有网友对这点进行了反驳并举证。

    其实负向查询并不绝对会索引失效,这要看MySQL优化器的判断,全表扫描或者走索引哪个成本低了。

    3. 索引字段可以为null,使用is null或is not null时,可能会导致索引失效

    其实单个索引字段,使用is null或is not null时,是可以命中索引的,但网友在举证时说两个不同索引字段用or连接时,索引就失效了,笔者认为确实索引失效,但这个锅应该由or来背,属于第一种场景~~

    假设USER表中的user_id列有索引且允许null,age列有索引且允许null。

    1

    select * from `user` where user_id is not null or age is not null;

    不过某些“军规”和规范中都有强调,字段要设为not null并提供默认值,是有原因值得参考的。

    • null的列使索引/索引统计/值比较都更加复杂,对MySQL来说更难优化。
    • null 这种类型MySQL内部需要进行特殊处理,增加数据库处理记录的复杂性;同等条件下,表中有较多空字段的时候,数据库的处理性能会降低很多。
    • null值需要更多的存储空,无论是表还是索引中每行中的null的列都需要额外的空间来标识。
    • 对null 的处理时候,只能采用is null或is not null,而不能采用=、in、<、<>、!=、not in这些操作符号。如:where name!='shenjian',如果存在name为null值的记录,查询结果就不会包含name为null值的记录。

    4. 在索引列上使用内置函数,一定会导致索引失效

    比如下面语句中索引列login_time上使用了函数,会索引失效:

    1

    select * from `user` where DATE_ADD(login_time, INTERVAL 1 DAY) = 7;

    优化建议,尽量在应用程序中进行计算和转换。

    其实还有网友提到的两种索引失效场景,应该都归于索引列使用了函数。

    4.1 隐式类型转换导致的索引失效

    比如下面语句中索引列user_id为varchar类型,不会命中索引:

    1

    select * from `user` where user_id = 12;

    这是因为MySQL做了隐式类型转换,调用函数将user_id做了转换。

    1

    select * from `user` where CAST(user_id AS signed int) = 12;

    4.2 隐式字符编码转换导致的索引失效

    当两个表之间做关联查询时,如果两个表中关联的字段字符编码不一致的话,MySQL可能会调用CONVERT函数,将不同的字符编码进行隐式转换从而达到统一。作用到关联的字段时,就会导致索引失效。

    比如下面这个语句,其中d.tradeid字符编码为utf8,而l.tradeid的字符编码为utf8mb4。因为utf8mb4是utf8的超集,所以MySQL在做转换时会用CONVERT将utf8转为utf8mb4。简单来看就是CONVERT作用到了d.tradeid上,因此索引失效。

    1

    select l.operator from tradelog l , trade_detail d where d.tradeid=l.tradeid and d.id=4;

    这种情况一般有两种解决方案。

    方案1: 将关联字段的字符编码统一。

    方案2: 实在无法统一字符编码时,手动将CONVERT函数作用到关联时=的右侧,起到字符编码统一的目的,这里是强制将utf8mb4转为utf8,当然从超集向子集转换是有数据截断风险的。如下:

    1

    select d.* from tradelog l , trade_detail d where d.tradeid=CONVERT(l.tradeid USING utf8) and l.id=2;

    5. 对索引列进行运算,一定会导致索引失效

    运算如+,-,*,/等,如下:

    1

    select * from `user` where age - 1 = 10;

    优化的话,要把运算放在值上,或者在应用程序中直接算好,比如:

    1

    select * from `user` where age = 10 - 1;

    6. like通配符可能会导致索引失效

    like查询以%开头时,会导致索引失效。解决办法有两种:

    将%移到后面,如:

    1

    select * from `user` where `name` like '李%';

    利用覆盖索引来命中索引。

    1

    select name from `user` where `name` like '%李%';

    7. 联合索引中,where中索引列违背最左匹配原则,一定会导致索引失效

    当创建一个联合索引的时候,如(k1,k2,k3),相当于创建了(k1)、(k1,k2)和(k1,k2,k3)三个索引,这就是最左匹配原则。

    比如下面的语句就不会命中索引:

    1

    2

    3

    select * from t where k2=2;

    select * from t where k3=3;

    slect * from t where k2=2 and k3=3;

    下面的语句只会命中索引(k1):

    1

    slect * from t where k1=1 and k3=3;

    8. MySQL优化器的最终选择,不走索引

    上面有提到,即使完全符合索引生效的场景,考虑到实际数据量等原因,最终是否使用索引还要看MySQL优化器的判断。当然你也可以在sql语句中写明强制走某个索引。

    优化索引的一些建议

    • 禁止在更新十分频繁、区分度不高的属性上建立索引。
      • 更新会变更B+树,更新频繁的字段建立索引会大大降低数据库性能。
      • “性别”这种区分度不大的属性,建立索引是没有什么意义的,不能有效过滤数据,性能与全表扫描类似。
    • 建立组合索引,必须把区分度高的字段放在前面。
    展开全文
  • MySQL 索引失效案例

    千次阅读 2019-10-29 11:10:56
    索引失效与优化 1、全值匹配我最爱 2、最佳左前缀法则(带头索引不能死,中间索引不能断) 如果索引了多个列,要遵守最佳左前缀法则。指的是查询从索引的最左前列开始 并且 不跳过索引中的列。 正确的示例参考上...
     

    案例所用的表结构、索引、与数据如下:

    这里写图片描述
    这里写图片描述

    索引失效与优化

    这里写图片描述

    1、全值匹配我最爱

    这里写图片描述

    2、最佳左前缀法则(带头索引不能死,中间索引不能断)

    如果索引了多个列,要遵守最佳左前缀法则。指的是查询从索引的最左前列开始 并且 不跳过索引中的列。
    正确的示例参考上图。

    错误的示例:
    带头索引死:
    这里写图片描述
    中间索引断(带头索引生效,其他索引失效):
    这里写图片描述

    3、不要在索引上做任何操作(计算、函数、自动/手动类型转换),不然会导致索引失效而转向全表扫描

    这里写图片描述

    4、mysql存储引擎不能继续使用索引中范围条件(bettween、<、>、in等)右边的列

    这里写图片描述

    5、尽量使用覆盖索引(只查询索引的列(索引列和查询列一致)),减少select *

    这里写图片描述

    6、索引字段上使用(!= 或者 < >)判断时,会导致索引失效而转向全表扫描

    这里写图片描述

    7、索引字段上使用 is null / is not null 判断时,会导致索引失效而转向全表扫描

    这里写图片描述

    8、索引字段使用like以通配符开头(‘%字符串’)时,会导致索引失效而转向全表扫描

    这里写图片描述
    由结果可知,like以通配符结束相当于范围查找,索引不会失效。与范围条件(bettween、<、>、in等)不同的是:不会导致右边的索引失效。

    问题:解决like ‘%字符串%’时,索引失效问题的方法?
    使用覆盖索引可以解决。
    这里写图片描述
    这里写图片描述

    9、索引字段是字符串,但查询时不加单引号,会导致索引失效而转向全表扫描

    这里写图片描述

    10、索引字段使用 or 时,会导致索引失效而转向全表扫描

    这里写图片描述

    小总结

    这里写图片描述

    这里写图片描述

    展开全文
  • 索引失效的情况

    2021-04-21 10:26:36
    1.条件中有or需要条件中每列都加上索引否则索引失效 2.组合索引没使用第一个索引的就会失效 3.like以%开头的会失效 like ‘%李’ 4.列类型是字符串的需要用引号引用起来,否则索引失效 5.索引列有函数运算的索引失效...

    1.条件中有or需要条件中每列都加上索引否则索引失效
    2.组合索引没使用第一个索引的就会失效
    3.like以%开头的会失效 like ‘%李’
    4.列类型是字符串的需要用引号引用起来,否则索引失效
    5.索引列有函数运算的索引失效
    6.查询条件有!=、<>号的索引失效
    7.not in会导致索引失效,in范围太大时会导致索引失效进行全表扫描
    8.尽量避免进行null值判断会导致索引失效 where a.id is null

    展开全文
  • SQL索引失效原因排查

    2019-08-17 13:01:33
    数据库有一张日志表,偶然发现日志表数据库索引失效,通过排查发现原因。 log 表会产生大量日志,所以定期会将表进行备份。 通过SQL查询发现索引失效 查看哪些索引失效 select index_name from user_indexes where ...
  • Mysql索引失效的原因

    千次阅读 2018-11-25 20:22:26
    Mysql索引失效的原因 1、最佳左前缀原则——如果索引了多列,要遵守最左前缀原则。指的是查询要从索引的最左前列开始并且不跳过索引中的列。 2、不在索引列上做任何操作(计算,函数,(自动或者手动)类型装换),...
  • Mysql索引失效

    2021-02-22 17:02:48
    一让走了索引,(所以不能轻易的说使用or索引失效了) 当我将or两边的查询条件换了,account_id并没有创建索引,此时查询没有走索引,走的全表扫描。 总结:or条件2边都创建索引,他还是走索引的,就如我第二...
  • 索引失效问题

    2021-02-16 13:44:11
    如何避免索引失效 尽量全值匹配; 最佳左前缀法则; 不要在索引上做任何操作(计算、函数、(自动或者手动)类型转换); 存储引擎不能使用索引中范围条件右边的列; 尽量使用覆盖索引(只访问索引的查询(索引列和...
  • 避免索引失效原则

    2020-05-06 16:14:09
    1、避免索引失效原则 1、复合索引,不要跨列或者无序使用(最佳左前缀) 2、复合索引,尽量使用全索引匹配 3、不要在索引上进行任何操作(比如:对索引进行类型转化,加减乘除计算等) 4、复合索引不能使用不等于...
  • SQL导致的索引失效

    2020-05-10 16:14:48
    我们在开发中会发现, 明明我这条SQL语句应该是用到了索引才对, 但是为何速度仍然那么慢, 其实是你的SQL写的有问题导致了索引失效, 我们来看下什么情况下MySQL的索引会失效 / 索引失效 / 对查询进行优化,尽量避免全...
  • mysql索引失效

    2019-11-19 00:54:14
    1.全值匹配我最爱。条件与索引一一对应 ...不要进行这些操作:计算、函数、自动/手动类型转换,不然会导致索引失效而转向全表扫描 4.范围条件右边的列失效。不能继续使用索引中范围条件(bettween、<、&...
  • 1、如何判断索引是否生效? 答:在查询语句前加上explain。 explain函数作用:显示了MYSQL如何使用索引来处理select语句以及连接表。 explain select id , name table where name like 'abc%' 2、索引失效的情况...
  • MySQL 索引失效的场景

    2021-03-14 21:36:03
    索引失效的场景1.1 隐式类型转换问题1.2 联合索引违反最左前缀匹配原则1.3 对索引列运算1.4 is null 判断1.5 like 使用不当1.6 对索引列使用函数1.7 in 使用不当1.8 or 使用不当1.9 查询优化不走索引2. 没必要建立...
  • 数据库索引失效类型

    2019-04-03 09:47:52
    由于mysql数据库的结构是B+数,一颗平衡的二叉树,二叉树的特性我们都知道是判断向左走还是向右走,因此如果说不能判断该索引是需要向左走还是向右走的情况下,则会索引失效。 因此,索引失效的类型可能有以下几种...
  • 索引失效

    2011-05-31 12:38:00
    在此仅讨论是否使用INDEX问题, 不涉及执行时间长短问题 IS NULL 或IS NOT NULL操作(判断字段是否为空) 判断字段是否为空一般是不会应用索引的,因为B树索引是不索引空值的。 SELECT * ...
  • 几乎所有的小伙伴都可以随口说几句关于创建索引的优缺点,也知道...以下介绍了一些可能会造成索引失效的特殊情况,希望大家在平时开发和面试的时候能够注意到! 一、如何判断数据库索引是否生效 首先在接着探讨...
  • MySQL数据库索引失效与优化详解 案例所用的表结构、索引、与数据如下: 索引失效与优化 全值匹配 最佳左前缀法则 不在索引列上做任何操作(计算、函数、(自动or手动)类型转换),会导致索引失效而转向全表扫描 ...
  • mysql 索引失效的场景

    2019-12-24 15:45:40
    索引失效的场景: like 以%开头,索引无效;当like前缀没有%,后缀有%时,索引有效。 or语句前后没有同时使用索引。当or左右查询字段只有一个是索引,该索引失效,只有当or左右查询字段均为索引时,才会生效...
  • MySQL高级 之 索引失效与优化详解

    万次阅读 多人点赞 2017-05-16 18:40:27
    索引失效与优化1、全值匹配我最爱2、最佳左前缀法则(带头索引不能死,中间索引不能断)如果索引了多个列,要遵守最佳左前缀法则。指的是查询从索引的最左前列开始 并且 不跳过索引中的列。 正确的示例参考上图。...
  • MySQL索引失效与优化

    2020-09-15 00:09:47
    索引失效: 1、索引字段上使用( != 、<>、is null、is not null )判断时,索引会失效,而转向全表扫描。 2、索引字段上使用通配符(%)开头,索引会失效,而转向全表扫描。 3、索引字段是字符串,但查询...
  • 索引失效和注意事项

    万次阅读 2018-08-24 16:27:03
    索引失效的情况 如果是同样的sql如果在之前能够使用到索引,那么现在使用不到索引,以下几种主要情况: 随着表的增长,where条件出来的数据太多,大于15%,使得索引失效(会导致CBO计算走索引花费大于走全表) ...
  • 说明:该篇文章主要是通过 explain 关键字分析索引是否失效,关于explain关键字各个关键字的说明可以查看:一文看懂MySQL中explain关键字的作用 前置工作 # 建表 CREATE TABLE staffs ( id INT PRIMARY KEY AUTO_...
  • 1 结合实例,介绍常见的几种索引失效场景,以及对每个场景会做一些额外的扩展说明. 2 后面写着写着跑题了,为了想给大家讲下什么是回表...然后。。。。 正文 失效 一 查询的字段列未添加索引 ps:这......
  • 1. 注意具有索引列的查询条件,避免造成索引失效(具体看如下的索引失效规则) 2. 对于数据重复多的列,无需建立索引 3. 索引并非越多越好,索引越多,对增删改的速度就会越慢 4. select 结果中,避免使用*符号...
  • MySQL高级之查询优化(索引失效) 文章目录MySQL高级之查询优化(索引失效)一、单表使用索引及常见的索引失效1.索引失效的案例2.建议二、关联查询优化三、子查询优化四、排序分组优化 一、单表使用索引及常见的索引失效...
  • 索引失效的几种情况

    2021-06-17 15:55:04
    索引失效 本文参考尚硅谷视频 口诀:带头大哥不能死,中间兄都不能断,索引列上无操作,范围右边全失效,like百分加右边,字符串中有引号 准备: 建立员工记录表staffs(id,name,age,pos,add_time) 给表中name,age,...
  • 13. 索引失效分析

    2020-07-03 20:40:41
    1. 全值匹配 # 条件与索引一一对应 explain select * from tuser where name = 'zhaoyun' and age = 1 and sex = '1'; 2. 最左前缀 ...# 中间索引断(带头索引生效,其他索引失效) explain select * from t
  • 日常SQL语句查询,部分SQL由于条件会导致索引失效,下面整理一些典型的SQL语句,优化索引生效,加快查询: 1、百分号索引失效,如果是LIKE 'MYSQL'则索引生效 注意: 1、索引中不能有%号,否则索引失效 例如在...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 54,113
精华内容 21,645
关键字:

如何判断索引失效