Mysql-索引

文章目录

索引实现原理

MySQL索引实现解析

最左匹配原则

MySQL索引最左匹配原则是什么

创建一个表格

sql 复制代码
CREATE TABLE `test` (  `a` int NOT NULL AUTO_INCREMENT,  
`b` int DEFAULT NULL,  
`c` int DEFAULT NULL,  
`d` int DEFAULT NULL,  
`e` int DEFAULT NULL,  
PRIMARY KEY(`a`),  
KEY `idx_abc` (`b`,`c`,`d`)) 
ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;  
INSERT INTO test(`a`, `b`, `c`, `d`, `e`) VALUES (1, 2, 3, 4, 5);
INSERT INTO test(`a`, `b`, `c`, `d`, `e`) VALUES (2, 2, 3, 4, 5);
INSERT INTO test(`a`, `b`, `c`, `d`, `e`) VALUES (3, 2, 3, 4, 5);

索引下推 (Using index condition)

shell 复制代码
mysql> explain SELECT * from test where b >1 and c = 1;
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-----------------------+
| id | select_type | table | partitions | type  | possible_keys | key     | key_len | ref  | rows | filtered | Extra                 |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-----------------------+
|  1 | SIMPLE      | test  | NULL       | range | idx_abc       | idx_abc | 5       | NULL |    2 |    33.33 | Using index condition |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)

索引覆盖 (Using index)

shell 复制代码
mysql> explain SELECT b, c, d FROM test WHERE d = 2;
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
| id | select_type | table | partitions | type  | possible_keys | key     | key_len | ref  | rows | filtered | Extra                    |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
|  1 | SIMPLE      | test  | NULL       | index | idx_abc       | idx_abc | 15      | NULL |    3 |    33.33 | Using where; Using index |
+----+-------------+-------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+
1 row in set, 1 warning (0.00 sec)

走联合索引

shell 复制代码
mysql> explain SELECT * FROM test where b = 2;
+----+-------------+-------+------------+------+---------------+---------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key     | key_len | ref   | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+---------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | test  | NULL       | ref  | idx_abc       | idx_abc | 5       | const |    3 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------+---------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.01 sec)

走主键索引

sql 复制代码
mysql> explain SELECT * FROM test whtest where a = 2;
+----+-------------+--------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
| id | select_type | table  | partitions | type  | possible_keys | key     | key_len | ref   | rows | filtered | Extra |
+----+-------------+--------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | whtest | NULL       | const | PRIMARY       | PRIMARY | 4       | const |    1 |   100.00 | NULL  |
+----+-------------+--------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

不走索引

shell 复制代码
mysql> explain SELECT * FROM test where c = 2;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | test  | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    3 |    33.33 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)

Explain重要字段

  • possible_keys:可能选择的索引
  • key:实际选择的索引
  • type : 链接类型,性能从好到坏:system > const > ref > index > all
    • system和const都是查询结果只有一行记录,sytem是特殊的join,查的是系统表。一般是主键索引或者唯一索引;
    • ref:当满足索引的最左前缀规则,或者索引不是主键也不是唯一索引时才会发生。走普通索引
    • index: 全表查询索引表
    • all:全表查询
  • rows: MySQL估算会扫描的行数,数值越小越好。
  • Extra : 展示有关本次查询的附加信息
    • Using index: The column information is retrieved from the table using only information in the index tree without having to do an additional seek to read the actual row. This strategy can be used when the query uses only columns that are part of a single index.
    • Using index condition:Tables are read by accessing index tuples and testing them first to determine whether to read full table rows. In this way, index information is used to defer ("push down") reading full table rows unless it is necessary.
    • Using where: 不管有没有通过索引查找,只要加载了数据到内存进行where条件筛选。

索引类型

  • Primary Key(主键)(聚簇索引):包含全量数据集

  • 普通索引

  • 唯一索引:索引列的值必须唯一,但允许有多个空值。若是组合索引,则列值的组合必须唯一。主键索引是一种特殊的唯一索引,不允许有空值

  • 组合索引

  • 全文索引聊一聊MySQL的全文检索

  • 短索引(前缀索引)

    • 创建前缀索引
    sql 复制代码
    CREATE TABLE test.t1 (
    col1 VARCHAR(10),
    col2 VARCHAR(20),
    INDEX (col1, col2(10))
    );
  • 倒排索引: "关键词" => "文档ID",即关键词到文档id的映射

数据库的NULL存储

索引下推

五分钟搞懂MySQL索引下推

filesort原理

order by 出现 using filesort根因分析及优化

  • 双路排序:
    读取行指针(即rowid)和order by列,对他们进行排序,然后扫描已经排序好的列表,按照列表中的值重新从列表中读取对应的数据输出。
    双路排序的开销可能会非常巨大,因为他会读取表两次,第二次读取会引发大量的随机IO,对于myisam涞说,这个代价尤其昂贵,myisam表利用系统调用去提取每行的数据。
  • 单路排序:
    读取查询需要的所有列,按照order by 列对他们进行排序,然后扫描排序后的列表进行输出,它的效率更快一些,避免了第二次读取数据。并且把随机IO变成了顺序IO,但是它会使用更多的空间,因为它把每一行都保存在内存中了。

如果需要排序的列的总大小加上order by列的大小超过了 max_length_for_sort_data定义的字节,mysql就会使用双路排序,当任何需要的列(甚至不是用来order by的列)是text.blob的时候,也会使用双路排序,(可以使用substtring() 把这些列转化为可以单路排序的列)。

参考

相关推荐
sunshine8853 分钟前
财务RPA的深水区应用:超越自动化,迈向智能决策支持
数据库
efir OONA13 分钟前
MySQL数据库误删恢复_mysql 数据 误删
数据库·mysql·adb
zhangchaoxies40 分钟前
如何在 Go 中安全复制接口指针所指向的值
jvm·数据库·python
陈陈CHENCHEN1 小时前
【数据库】MySQL 8.0.40 至 8.0.44 RPM 方式升级指南
数据库·mysql
Azhao11062 小时前
一文读懂分享网站模块介绍(附实操教程)
mysql
m0_734949792 小时前
怎么利用Navicat进行调整备份文件压缩等级_详细配置与操作步骤
jvm·数据库·python
T.i.s2 小时前
番外续2-MIT-BIH Arrhythmia Database
数据库
有味道的男人2 小时前
AI 效率翻倍:对接 1688 拍立淘接口,商品全量信息一键抓取
数据库
m0_741173333 小时前
如何处理SQL中的NULL值_使用ISNULL或COALESCE函数
jvm·数据库·python
志栋智能3 小时前
超自动化巡检:解锁运维数据的深层价值
运维·服务器·数据库·自动化