【实测版】联合索引,最左匹配原则,走?不走?

有目标就不怕路远。年轻人.无论你现在身在何方.重要的是你将要向何处去。只有明确的目标才能助你成功。没有目标的航船.任何方向的风对他来说都是逆风。因此,再遥远的旅程,只要有目标.就不怕路远。没有目标,哪来的劲头?一车尔尼雷夫斯基

导读:本篇文章讲解 【实测版】联合索引,最左匹配原则,走?不走?,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

本文基本基于Explain做分析,如果不太了解可以先移步下文(。・ω・。)ノ

了解MySQL的Explain,读这一篇够了( ̄∇ ̄)/

开始✊✊✊

建表

我们先创建一个表

CREATE TABLE `aqin_index` (
    `id` BIGINT(20) UnSIGNED NOT NULL AUTO_INCREMENT,
    `name` VARCHAR(50) NOT NULL,
    `card_no` VARCHAR(50) NOT NULL,
    `time_created` DATETIME DEFAULT CURRENT_TIMESTAMP,
    `note` VARCHAR(100) NOT NULL,
    PRIMARY KEY (`id`),
    INDEX `index_unit` (`name`,`time_created`,`card_no`) USING BTREE) 
    ENGINE=InnoDB DEFAULT CHARSET=utf8;
【实测版】联合索引,最左匹配原则,走?不走?

Message字段显示OK则表示创建成功

这里创建的时候直接添加了一个联合索引

【实测版】联合索引,最左匹配原则,走?不走?

INDEX 索引名称 (字段1,字段2,字段3) USING 索引方法
  • 索引名称:自己起个就成

  • 字段1,字段2,字段3:想要添加的联合索引的所有字段(需要注意顺序)

  • 索引方法:一般选择BTREE(BTREE/HASH)

也可以在现有的表中添加

ALTER TABLE `aqinindex`  ADD INDEX `index_unit` (`name`,`time_created`,`card_no`)

插入数据

创建函数

-- 插入百万数据
DELIMITER $$
CREATE FUNCTION mock_data_4_aqin_index()
RETURNS INT

BEGIN
        DECLARE num INT DEFAULT 1000000;
  DECLARE i INT DEFAULT 0;
        
  WHILE i < num DO
  -- 插入语句
  INSERT INTO `aqin_index`(`name`,`card_no`,`note`)VALUES
  (CONCAT('name-',i), CONCAT('18', FLOOR(RAND()*((999999999-100000000)+100000000))),
  CONCAT('note-',FLOOR(RAND()*2), UUID(), FLOOR(RAND()*100)));
     SET i = i+1;
   END WHILE;
   RETURN i;
        
END;
【实测版】联合索引,最左匹配原则,走?不走?

Message字段显示如上图即为执行成功

调用函数

SELECT mock_data_4_aqin_index()
【实测版】联合索引,最左匹配原则,走?不走?

Message字段显示如上图即为执行成功,瞅一眼咱们生成的数据

【实测版】联合索引,最左匹配原则,走?不走?

删除函数

DROP FUNCTION 函数名
  • 注意⚠️此处的函数名是不加括号的

我们浅浅的测试下

执行测试语句

EXPLAIN select  * from aqin_index where name = 'name-9999' and time_created="2023-01-09 16:37:56" and `card_no` = '18432153441'
【实测版】联合索引,最左匹配原则,走?不走?

可以看出type类型是ref,key_len值为310(三个字段长度和),走了联合索引并且3个字段都用上了

计算方式可以参考了解MySQL的Explain,读这一篇够了( ̄∇ ̄)/

  1. 替换三个字段的顺序

【实测版】联合索引,最左匹配原则,走?不走?

各个参数无变化

结论:字段都有,换顺序对结果无影响

  1. 删除第一个字段

【实测版】联合索引,最左匹配原则,走?不走?

type类型是ALL,即走了全表查询

结论:第一个字段缺失则不走索引

  1. 删除其他字段

【实测版】联合索引,最左匹配原则,走?不走?

type类型是ref,key_len值为158,用到了联合索引,但是只用了两个字段(name和time_created)

结论:第一个字段存在,就会使用联合索引,其他字段缺少只会影响用到索引的字段数

特殊情况

【实测版】联合索引,最左匹配原则,走?不走?

【实测版】联合索引,最左匹配原则,走?不走?

分析下上面两张图,他们的type类型是index,使用了全索引扫描,相比较ref挺慢的其实

【实测版】联合索引,最左匹配原则,走?不走?

【实测版】联合索引,最左匹配原则,走?不走?

分析下上面两张图,他们的区别在于查询的字段是否被联合索引覆盖,card_no在联合索引中,type类型是index,note不在type类型是ALL,index的性能虽然不如ref但优于全表扫描ALL

总结

联合索引的各个字段可以不按顺序出现(原因是WHERE后面字段的顺序会被优化器优化为符合最左前缀的顺序),但是第一个字段必须出现,否则不走索引(最左前缀匹配,即WHERE条件必须有联合索引的第一个字段,以最左边的为起点任何连续的索引都能匹配上),当SELECT后需要查询的字段被联合索引覆盖,也会走索引,但方式是进行全索引扫描,效率并不高

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/135356.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!