文章目录

  • 1. MySQL索引概述
    • 1.1 索引的概念
    • 1.2 索引的特点
    • 1.3 索引的分类
    • 1.4 索引的使用场景
  • 2. 索引失效场景
    • 2.1 索引失效9种场景
    • 2.2 索引失效场景总结
  • 3. 索引失效验证
    • 3.1 全值匹配
    • 3.2 最佳左前缀
    • 3.3 索引计算
    • 3.4 索引范围:索引列上不能有范围查询
    • 3.5 索引覆盖:尽量使用覆盖索引
    • 3.6 不等: 使用不等于(!= 或者 <>)的时候
    • 3.7 null:字段的is not null 与is null
    • 3.8 like:like的前后模糊匹配
    • 3.9 or:减少使用or

1. MySQL索引概述

1.1 索引的概念

什么是索引,索引就是排好序的快速查找数据结构。

1.2 索引的特点

索引的优点
1.提高数据检索的效率, 降低数据库的IO成本。

2.通过索引列对数据进行排序, 降低数据排序的成本, 降低了CPU的消耗。

索引的缺点
1.虽然索引大大提高了查询速度, 同时却会降低更新表的速度, 如对表进行INSERT、 UPDATE和DELETE。 因为更新表时, MySQL不仅要保存数据, 还要保存一下索引文件每次更新添加了索引列的字段, 都会调整因为更新所带来的键值变化后的索引信息。

2.实际上索引也是一张表, 该表保存了主键与索引字段, 并指向实体表的记录, 所以索引列也是要占用空间的。

1.3 索引的分类

MySQL 使用的是 Btree 索引。另外还有B+tree 索引,B-tree 索引,具体原理不在细说,原理详情参考官网。
简单说下以下几个常用索引。

单值索引
概念:即一个索引只包含单个列, 一个表可以有多个单列索引

唯一索引
概念: 索引列的值必须唯一, 但允许有空值

主键索引
概念: 设定为主键后数据库会自动建立索引, innodb为聚簇索引。

复合索引
概念: 即一个索引包含多个列

1.4 索引的使用场景

适合创建索引的情况
1.主键自动建立唯一索引;
2.频繁作为查询条件的字段应该创建索引
3.查询中与其它表关联的字段, 外键关系建立索引
4.单键/组合索引的选择问题, 组合索引性价比更高
5.查询中排序的字段, 排序字段若通过索引去访问将大大提高排序速度
6.查询中统计或者分组字段

不适合创建索引的情况
1.表记录太少
2.经常增删改的表或者字段
3.Where 条件里用不到的字段不创建索引
4.过滤性不好的不适合建索引

2. 索引失效场景

2.1 索引失效9种场景

1.全值匹配:查询条件的列与索引列的字段,顺序完全相同。
2. 最佳左前缀:查询条件的列与索引列的字段相同,顺序不同,从不同顺序列开始后边都不走索引。
3. 索引计算:不要在索引上做任何计算
4. 索引范围:索引列上不能有范围查询,比如大于,小于,大于等于,小于等于。
5. 索引覆盖:尽量使用覆盖索引
6. 不等: 使用不等于(!= 或者 <>)的时候
7. null:字段的is not null 与is null
8. like:like的前后模糊匹配
9. or:减少使用or

2.2 索引失效场景总结

全值匹配,左前缀。
索引计算范围要覆盖。
不等于(!= 或者 <>)扫全表,null走索引,not不走。
like模后不模前,见or就走union all

3. 索引失效验证

索引测试环境
1.mysql版本:5.7.27-log,查询语句:select VERSION();
2.建表语句及数据:mysql批量插入数据

3.1 全值匹配

-- 全值匹配
-- 查看sql执行计划
EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHERE emp.age=30;
EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHERE emp.age=30 and deptid=4;
EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHERE emp.age=30 and deptid=4 AND emp.name = 'abcd';-- 创建联合索引
CREATE INDEX idx_age_deptid_name ON emp(age,deptid,NAME);

创建索引前

创建索引后

3.2 最佳左前缀

-- 创建索引
CREATE INDEX idx_age_deptid_name ON emp(age,deptid,NAME);
-- 缺少联合索引的第一个字段
explain select sql_no_cache * from emp where deptId = 4 and name = 'abcd';
-- 联合索引的第一二个字段,缺少最后一个字段
explain select sql_no_cache * from emp where age = 30 and deptId = 4;
-- 联合索引的第一三各字段,缺少第二个字段
explain select sql_no_cache * from emp where age = 30 and name = 'abcd' ;

查询字段与索引字段顺序的不同会导致, 索引无法充分使用, 甚至索引失效!
原因: 使用复合索引, 需要遵循最佳左前缀法则, 即如果索引了多列, 要遵守最左前缀法则。 指的是查询从索引的最左前列开始并且不跳过索引中的列。
结论: 过滤条件要使用索引必须按照索引建立时的顺序, 依次满足, 一旦跳过某个字段, 索引后面的字段都无法被使用

3.3 索引计算

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

1.在查询列上使用函数

-- 索引不带计算
EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHERE age=30;
-- 索引字段计算
EXPLAIN SELECT SQL_NO_CACHE * FROM emp WHERE LEFT(age,3)=30;


\2. 在查询列上做了转换

-- 创建单值索引,字符串类型 name
create index idx_name on emp(name);
-- 字符串加单引号情况
explain select sql_no_cache * from emp where name='30000';
-- 字符串不加单引号, 则会在 name 列上做一次转换!
explain select sql_no_cache * from emp where name=30000;

3.4 索引范围:索引列上不能有范围查询

explain SELECT SQL_NO_CACHE * FROM emp WHERE emp.age=30 and deptid=5 AND emp.name = 'abcd';
explain SELECT SQL_NO_CACHE * FROM emp WHERE emp.age=30 and deptid<=5 AND emp.name = 'abcd';

建议: 将可能做范围查询的字段的索引顺序放在最后

3.5 索引覆盖:尽量使用覆盖索引

explain SELECT SQL_NO_CACHE * FROM emp WHERE emp.age=30 and deptId=4 and name='XamgXt';
explain SELECT SQL_NO_CACHE age,deptId,name FROM emp WHERE emp.age=30 and deptId=4 and name='XamgXt';

3.6 不等: 使用不等于(!= 或者 <>)的时候

mysql 在使用不等于(!= 或者<>)时, 有时会无法使用索引会导致全表扫描。

3.7 null:字段的is not null 与is null

当字段允许为 Null 的条件下:
is not null 用不到索引, is null 可以用到索引。

3.8 like:like的前后模糊匹配

前缀不能出现模糊匹配!

3.9 or:减少使用or

使用 union all 或者 union 来替代:

MySQL数据库索引及失效场景相关推荐

  1. 范围查找(比如日期范围)下查询出现全表扫描MySQL数据库索引失效

    范围查找(比如日期范围)下查询出现全表扫描MySQL数据库索引失效 当下MySQL数据库在多款数据库中脱颖而出,成为使用最广泛的数据库之一,这里我们来看看数据库索引上的一个问题.我们知道在数据量上去以 ...

  2. 深度解密Mysql数据库索引

    文章目录 深度理解Mysql数据库索引 Mysql索引的基本概念 索引分类 Mysql中索引的语法 创建索引 删除索引 查看表中的索引 查看查询语句使用索引的情况 索引的优缺点 优点 缺点 索引的实现 ...

  3. 知识点:Mysql 数据库索引优化实战(4)

    知识点:Mysql 索引原理完全手册(1) 知识点:Mysql 索引原理完全手册(2) 知识点:Mysql 索引优化实战(3) 知识点:Mysql 数据库索引优化实战(4) 一:插入订单 业务逻辑:插 ...

  4. 面试必问:一文弄懂MySQL数据库索引之底层数据结构和索引类型

    面试必问:一文弄懂MySQL数据库索引之底层数据结构和索引类型 前言 一.索引 1.1作用 1.2特点 1.3使用 1.3.1创建索引 1.3.2删除索引 1.3.3查看表中的索引 1.3.4查看SQ ...

  5. 为什么MySQL数据库索引选择使用B+树?

    在进一步分析为什么MySQL数据库索引选择使用B+树之前,我相信很多小伙伴对数据结构中的树还是有些许模糊的,因此我们由浅入深一步步探讨树的演进过程,在一步步引出B树以及为什么MySQL数据库索引选择使 ...

  6. MYSQL数据库-索引

    MYSQL数据库-索引 零.前言 一.索引概念 二.认识磁盘 三.理解索引 1.如何理解Page 2.B+ vs B 3.聚簇索引 VS 非聚簇索引 4.普通索引 5.总结 四.索引操作 1.创建索引 ...

  7. MySQL数据库索引的最左匹配原则((a),(a,b),(a,b,c)都能用到索引,(a,c)呢?)

    MySQL数据库索引的最左匹配原则 一. 联合索引说明 二. 那ac是否能用到索引呢? 三. 思考 四. 最左匹配原则的成因 一. 联合索引说明 建立三个字段的联合索引 联合索引(a,b,c)相当于建 ...

  8. mysql数据库-索引基础篇

    1.索引介绍 1.索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),他们包含着对数据表里所有记录的引用指针.是一种数据结构是一种数据库系统中排序的数据结构,以协助快速查询,更新 ...

  9. java如何实现e的次方_Java开发如何更改MySQL数据库datadir目录之MySQL数据库索引实现...

    引言 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品.MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 ...

最新文章

  1. LeetCode中等题之根据字符出现频率排序
  2. 在Laravel中使用Middleware进行身份验证
  3. 博物馆守卫问题(世界名画展览馆)
  4. 更改linux子系统软件源为国内镜像
  5. 判断点在直线的哪一侧_【倒车入库】车身是否“正直”该怎么判断?
  6. 排序算法—归并排序(思维导图思路整理)
  7. No matching distribution found for docx(配置cmd控制台代理)
  8. 基于QT实现的钢琴软件 (MFC大作业)
  9. 斐讯路由器k3c虚拟服务器,斐讯K3C路由器32.1.26.175如何打开telnet升级到官改固件教程...
  10. 个人网站、个人博客的设计案例,仅供参考
  11. Calendar计算两个日期相差几个月
  12. Python数据分析之股票数据
  13. python学习之类
  14. oracle单列转行,oracle 两种列转行的方式
  15. oracle SO币种默认设置,Oracle EBS 11i 表结构——OE模块 so_headers_all;so_lines_all
  16. 安卓非微信内置浏览器中的网页调起微信支付的方案研究
  17. git提交失败running pre-commit hook: lint-staged [33m‼ Some of your tasks use `git add` command
  18. Android Studio报错Could not find any version that matches com.android.support:appcompat-v7:33.+.
  19. 网络程序设计——VC的多线程编程(线程与进程)
  20. 用手机远程控制电脑的软件 ---TeamViewer远程控制

热门文章

  1. linux环境OpenRASP使用教程,集成openRASP与攻击测试
  2. php如何输出复选框的值,php 怎么输出复选框呢?
  3. 程序员简历工作模式_简历的完整形式是什么?
  4. java clock计时_Java Clock类| systemDefaultZone()方法与示例
  5. ps如何修改图片大小尺寸_PS新手入门教程:学习如何修改画布的大小
  6. python预定义_【Python】python类中方法的预定义
  7. ruby推送示例_Ruby直到示例循环
  8. Java OutputStreamWriter flush()方法与示例
  9. 二叉树的前序、中序、后续、层序遍历(包含递归与非递归)
  10. Python操作mySql数据库封装类