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() 把这些列转化为可以单路排序的列)。

参考

相关推荐
小乌龟不会飞8 分钟前
Ubuntu 安装 etcd 与 etcd-cpp-apiv3
数据库·etcd
古月居GYH3 小时前
【数据分析】如何在PyCharm中高效配置和使用SQL
ide·sql·pycharm
程序员岳焱7 小时前
Java 与 MySQL 性能优化:Java 实现百万数据分批次插入的最佳实践
后端·mysql·性能优化
计算机毕设定制辅导-无忧学长8 小时前
西门子 PLC 与 Modbus 集成:S7-1500 RTU/TCP 配置指南(一)
服务器·数据库·tcp/ip
程序员柳8 小时前
基于微信小程序的校园二手交易平台、微信小程序校园二手商城源代码+数据库+使用说明,layui+微信小程序+Spring Boot
数据库·微信小程序·layui
梦在深巷、9 小时前
MySQL/MariaDB数据库主从复制之基于二进制日志的方式
linux·数据库·mysql·mariadb
IT乌鸦坐飞机9 小时前
ansible部署数据库服务随机启动并创建用户和设置用户有完全权限
数据库·ansible·centos7
IT_10249 小时前
Spring Boot项目开发实战销售管理系统——数据库设计!
java·开发语言·数据库·spring boot·后端·oracle
Johny_Zhao9 小时前
Ubuntu系统安装部署Pandawiki智能知识库
linux·mysql·网络安全·信息安全·云计算·shell·yum源·系统运维·itsm·pandawiki
祁思妙想10 小时前
八股学习(三)---MySQL
数据库·学习·mysql