千家信息网

sql会导致索引失效吗

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,小编给大家分享一下sql会导致索引失效吗,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!前言网上经常能看到一些文章总结在 m
千家信息网最后更新 2026年11月01日sql会导致索引失效吗

小编给大家分享一下sql会导致索引失效吗,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

前言

网上经常能看到一些文章总结在 mysql 中不能命中索引的各种情况,其中有一种说法就是指使用了 or 的语句都不能命中索引。

这种说法其实是不够正确的,正确的结论应该是,从 mysql5.0 后,如果在 or 连接的字段上都有独立的索引的话,是可以命中索引的,这里就是用到了 index_merge 特性。

在 mysql5.0 版本以前一条 sql 只能选择使用一个索引,而且如果 sql 中使用了 or 关键字,那么已有的索引就会失效,会走全表扫描。因为无论走哪个索引,mysql 都不能一次性查找出符合条件的数据,所以只能放弃索引。

mysql 也是一直在不断升级更新,所以在 mysql5.0 版本后,增加了 index_merge 索引合并这个特性,也因此支持了一条 sql 使用多个索引。

index_merge 核心思想就是先分别使用单个索引查出满足要求的数据,然后再将这些数据合并到一起返回。
我们可以看一个的例子。

这里依然沿用我们前面文章中创建的表和测试数据,表中插入了 10 w 条测试数据,表结构如下。

CREATE TABLE `t` ( `id` int(11) NOT NULL, `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB;

我们先来给 a 字段添加一个索引,然后执行一条带 or 的查询语句看看。

mysql> alter table t add index a_index(a);Query OK, 0 rows affected (0.17 sec)Records: 0 Duplicates: 0 Warnings: 0
mysql> explain select a from t where a=100 or b=6000;+----+-------------+-------+------+---------------+------+---------+------+--------+-------------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows  | Extra    |+----+-------------+-------+------+---------------+------+---------+------+--------+-------------+| 1 | SIMPLE   | t   | ALL | a_index    | NULL | NULL  | NULL | 100332 | Using where |+----+-------------+-------+------+---------------+------+---------+------+--------+-------------+1 row in set (0.00 sec)

因为字段 b 上没有索引,mysql 认为走全表扫描代价更低一些,因为可以免去回表过程。

那么我们给 b 字段也加上索引试试,然后再执行刚刚那条 sql 。

mysql> alter table t add index b_index(b);Query OK, 0 rows affected (0.17 sec)Records: 0 Duplicates: 0 Warnings: 0
mysql> explain select a from t where a=100 or b=6000;+----+-------------+-------+-------------+-----------------+-----------------+---------+------+------+-------------------------------------------+| id | select_type | table | type    | possible_keys  | key       | key_len | ref | rows | Extra                   |+----+-------------+-------+-------------+-----------------+-----------------+---------+------+------+-------------------------------------------+| 1 | SIMPLE   | t   | index_merge | a_index,b_index | a_index,b_index | 5,5   | NULL |  2 | Using union(a_index,b_index); Using where |+----+-------------+-------+-------------+-----------------+-----------------+---------+------+------+-------------------------------------------+1 row in set (0.00 sec)

这回可以看到 mysql 同时使用了 a、b 两个索引,并且看到 type 字段的值为 index_merge。

接下来再来看另一条 sql,看看结果又是怎样的。

mysql> explain select a from t where a>100 or b>6000;+----+-------------+-------+------+-----------------+------+---------+------+--------+-------------+| id | select_type | table | type | possible_keys  | key | key_len | ref | rows  | Extra    |+----+-------------+-------+------+-----------------+------+---------+------+--------+-------------+| 1 | SIMPLE   | t   | ALL | a_index,b_index | NULL | NULL  | NULL | 100332 | Using where |+----+-------------+-------+------+-----------------+------+---------+------+--------+-------------+1 row in set (0.00 sec)

这条 sql 仅仅是把等号改成了大于号,也就是说返回的结果集是一个区间集,mysql 在这里又放弃了索引,走的全表扫描,不过有看文章说在 mysql5.7 版本后优化了这个问题,即在区间查询中也支持使用 index_merge,我的版本是 5.6 ,暂未验证这个优化,有兴趣的可以去验证下。

其实在 mysql 中很多东西都是不绝对的,对于同一条 sql 不同 mysql 版本的内部处理方式有可能是不太一样的,同时也可以看到 mysql 一直在不断优化升级,一些老旧的知识点很容易就会不再适用了。

以上是"sql会导致索引失效吗"这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注行业资讯频道!

索引 字段 数据 版本 就是 文章 篇文章 不断 内容 区间 同时 特性 知识 结果 语句 说法 升级 支持 查询 测试 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 保险科技 互联网保险 互联网科技公司起名 金融科技还是互联网 互联网下的科技发展 广州互联网科技公司 北京互联网科技有限公司 互联网科技革命 上海喔噻互联网科技 广州互联网络科技有限公司 青海省互联网新科技 互联网科技公司需要的职位 中盈科技互联网信息有限公司 成都铂石互联网科技做什么的 世界互联网科技公司市值排名 广州新华互联网科技学校电竞方面 徐州市互联网科技有限公司 城市宝互联网科技有限公司 互联网科技对化妆品行业 知域互联网科技有限公司官网 广州全民伙伴互联网科技有限公司 手磨咖啡 互联网科技有限公司经营范围 互联网科技项目计划书材料类 互联网金融科技名词解释 小米互联网科技园入驻 皮皮虾互联网科技有限公司 富国互联网科技002692 易企秀互联网科技是做什么的 10位科技互联网大佬 小牛互联网科技有限公司地址
0