• 全表扫描、全索引扫描、覆盖索引


    准备

    版本:Mysql 8

    本片文章参考自https://www.cnblogs.com/jpfss/p/9176147.html

    本篇原文:《全表扫描、全索引扫描、覆盖索引》

    创建语句

    1. CREATE TABLE IF NOT EXISTS `sanguo` (
    2. `id` int NOT NULL AUTO_INCREMENT,
    3. `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
    4. `age` int NOT NULL,
    5. `sex` int DEFAULT NULL,
    6. `zw` int DEFAULT NULL,
    7. PRIMARY KEY (`id`),
    8. KEY `idx_name_age` (`name`,`age`) USING BTREE
    9. ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

    生成测试数据 

    1. SET GLOBAL log_bin_trust_function_creators=TRUE;
    2. DELIMITER $$
    3. CREATE FUNCTION mock_data()
    4. RETURNS INT
    5. BEGIN
    6. DECLARE num INT DEFAULT 1000000;
    7. DECLARE i INT DEFAULT 0;
    8. WHILE i < num DO
    9. INSERT INTO sanguo(`name`,`age`,`sex`,`zw`)
    10. VALUES( CONCAT('用户',i), FLOOR(RAND() * 100), 1, FLOOR(RAND() * ((999999999 - 100000000) + 1000000000)));
    11. SET i = i + 1;
    12. END WHILE;
    13. RETURN i;
    14. END;
    15. -- 执行函数
    16. SELECT mock_data();

    参考:MySQL生成百万条数据超详细步骤_Eric-x的博客-CSDN博客_mysql百万数据

    开启性能分析

    set profiling=1;

    全表扫描

    Type列为 ALL。顺序读磁盘文件。

    1. mysql> explain SELECT zw FROM sanguo ;
    2. +----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------+
    3. | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
    4. +----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------+
    5. | 1 | SIMPLE | sanguo | NULL | ALL | NULL | NULL | NULL | NULL | 8 | 100.00 | NULL |
    6. +----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------+

    全索引扫描

    Type列为 index。遍历索引树获取数据。非密集数据会产生随机IO。

    1. mysql> explain SELECT name FROM sanguo ;
    2. +----+-------------+--------+------------+-------+---------------+--------------+---------+------+------+----------+-------------+
    3. | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
    4. +----+-------------+--------+------------+-------+---------------+--------------+---------+------+------+----------+-------------+
    5. | 1 | SIMPLE | sanguo | NULL | index | NULL | idx_name_age | 206 | NULL | 8 | 100.00 | Using index |
    6. +----+-------------+--------+------------+-------+---------------+--------------+---------+------+------+----------+-------------+

    覆盖索引

    Extra列为 Using index。无需回表

    1. mysql> explain SELECT id FROM sanguo ;
    2. +----+-------------+--------+------------+-------+---------------+--------------+---------+------+------+----------+-------------+
    3. | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
    4. +----+-------------+--------+------------+-------+---------------+--------------+---------+------+------+----------+-------------+
    5. | 1 | SIMPLE | sanguo | NULL | index | NULL | idx_name_age | 206 | NULL | 8 | 100.00 | Using index |
    6. +----+-------------+--------+------------+-------+---------------+--------------+---------+------+------+----------+-------------+

    全表扫描VS全索引扫描

    那个性能好,取决于数据存储的位置。

    • 如果在内存,速度应该差不多。
    • 如果数据在磁盘,那么全表扫描更好。原因是顺序读。

    全索引扫描+覆盖索引

    从性能分析的结果来看,全索引扫描+覆盖索引的组合性能相对较优。

    1. SELECT id FROM sanguo;
    2. SELECT `name` FROM sanguo ;
    3. SELECT zw FROM sanguo ;
    4. SELECT * FROM sanguo ;
    5. show profiles;

    关于profiles:MySQL :: MySQL 8.0 Reference Manual :: 13.7.7.30 SHOW PROFILE Statement

  • 相关阅读:
    SpringAOP详解
    Groovy语法&Gradle配置学习笔记
    少儿编程语言C++和python比较
    高校学生档案管理系统(Angularjs+HTML+CSS+bootstrap)
    JavaScript - canvas - 将图片保存到本地
    Java框架 Spring5--JdbcTemplate
    Kubernetes:(十二)k8s的控制器们
    【正点原子I.MX6U-MINI应用篇】9、嵌入式Linux中的多线程编程pthread
    CentOS卸载LVM磁盘的方法
    mysql必知必会
  • 原文地址:https://blog.csdn.net/qq_38974073/article/details/127750730