IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> MySQL索引失效的原因记录总结【更新中】 -> 正文阅读

[大数据]MySQL索引失效的原因记录总结【更新中】


title: “MySQL索引失效的原因记录总结”
date: 2022-03-22T14:55:56+08:00
draft: false


0 引言

好记性不如烂笔头,把常见的一些 MySQL 索引失效的问题记录下来,在工作中可以时时检查对比。

主要分为两个部分,explain 介绍和各种索引失效场景的模拟。

建表语句

CREATE TABLE `people` (
  `id` int unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '姓名',
  `gender` tinyint unsigned DEFAULT NULL COMMENT '性别,0男1女',
  `career` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '技能',
  `skills` varchar(30) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '技能',
  `birthday` date DEFAULT NULL COMMENT '出生日期',
  `lifetime` int DEFAULT NULL COMMENT '寿命',
  `gmt_create` timestamp NULL DEFAULT NULL COMMENT '入库时间',
  PRIMARY KEY (`id`),
  KEY `idx_career_skills_lifetime` (`career`,`skills`,`lifetime`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

explain 执行计划各属性解释说明

select_type

select_type说明
SIMPLE简单查询
PRIMARY最外层查询
SUBQUERY映射为子查询
DERIVED子查询
UNION联合
UNION RESULT使用联合的结果

type

type说明
ALL全数据表扫描
index全索引表扫描
RANGE对索引列进行范围查询
INDEX_MERGE合并索引,使用多个单列索引查询
REF根据索引查找一个或多个值
EQ_REF搜索时使用 primary key 或 unique 类型
CONST常量,表最多有一个匹配行,因为仅有一行,在这行的列值可被优化器剩余部分认为是常数,const表很快,因为它们只读取一次。
SYSTEM系统,表仅有一行(=系统表)。这是const联接类型的一个特例。
  • 性能:all < index < range < index_merge < ref_or_null < ref < eq_ref < system/const

  • 性能在 range 之下基本都可以进行调优

possible_keys

可能使用的索引

key

真实使用的

key_len

MySQL中使用索引字节长度

rows

mysql 预估为了找到所需的行而要读取的行数

extra

extra说明
Using index此值表示mysql将使用覆盖索引,以避免访问表。
Using wheremysql 将在存储引擎检索行后再进行过滤,许多where条件里涉及索引中的列,当(并且如果)它读取索引时,就能被存储引擎检验,因此不是所有带where子句的查询都会显示“Using where”。有时“Using where”的出现就是一个暗示:查询可受益于不同的索引。
Using temporarymysql 对查询结果排序时会使用临时表。
Using filesortmysql会对结果使用一个外部索引排序,而不是按索引次序从表里读取行。mysql有两种文件排序算法,这两种排序方式都可以在内存或者磁盘上完成,explain不会告诉你mysql将使用哪一种文件排序,也不会告诉你排序会在内存里还是磁盘上完成。
Range checked for each record(index map: N)没有好用的索引,新的索引将在联接的每一行上重新估算,N是显示在possible_keys列中索引的位图,并且是冗余的

1 不符合最左前缀原则

mysql> explain select * from people where `lifetime` = 23 and `skills` = '口才';
+----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table  | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | people | NULL       | ALL  | NULL          | NULL | NULL    | NULL |   14 |     7.14 | Using where |
+----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

说明:

  • 最左前缀原则指的是从索引最左前列开始并且不跳过索引中的列

  • type 是 ALL, 表示查询语句是全表数据查询,where 的查询条件是 lifetime 和 skills,缺少 career 这个索引条件,无法命中索引 idx_career_skills_lifetime。

2 在索引列上有多余操作,如:函数、计算、类型转换

mysql> explain select * from people where left(career, 2) = '群众';
+----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table  | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | people | NULL       | ALL  | NULL          | NULL | NULL    | NULL |   14 |   100.00 | Using where |
+----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------------+

说明:

  • LEFT()函数是一个字符串函数,它返回具有指定长度的字符串的左边部分。
  • LEFT()函数的语法:LEFT(str,length);
    • str是要提取子字符串的字符串。
    • length是一个正整数,指定将从左边返回的字符数。
    • LEFT()函数返回str字符串中最左边的长度字符。
    • 如果strlength参数为NULL,则返回NULL值。
    • 如果length0或为负,则LEFT函数返回一个空字符串。
    • 如果length大于str字符串的长度,则LEFT函数返回整个str字符串。
    • 请注意,SUBSTRINGSUBSTR 函数也提供与LEFT函数相同的功能。
  • career 字段是有索引的,但是执行计划中看到的却没有命中,说明在索引字段上添加多余操作会使其失效

3 查询条件有!=><

4 like以通配符%为开头

5 使用来了or

6 使用了is null或者is not null

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-03-24 00:37:48  更:2022-03-24 00:38:09 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 7:07:34-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码