MySQL组合索引与最左匹配原则详解

 更新时间:2019年03月16日 11:17:35   作者:Wolf、Heart  
这篇文章主要给大家介绍了关于MySQL组合索引与最左匹配原则的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Mysql具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧

前言

之前在网上看到过很多关于mysql联合索引最左前缀匹配的文章,自以为就了解了其原理,最近面试时和面试官交流,发现遗漏了些东西,这里自己整理一下这方面的内容。

什么时候创建组合索引?

当我们的where查询存在多个条件查询的时候,我们需要对查询的列创建组合索引

为什么不对没一列创建索引

  • 减少开销
  • 覆盖索引
  • 效率高

减少开销:假如对col1、col2、col3创建组合索引,相当于创建了(col1)、(col1,col2)、(col1,col2,col3)3个索引
覆盖索引:假如查询SELECT col1, col2, col3 FROM 表名,由于查询的字段存在索引页中,那么可以从索引中直接获取,而不需要回表查询

效率高:对col1、col2、col3三列分别创建索引,MySQL只会选择辨识度高的一列作为索引。假设有100w的数据,一个索引筛选出10%的数据,那么可以筛选出10w的数据;对于组合索引而言,可以筛选出100w*10%*10%*10%=1000条数据

最左匹配原则

假设我们创建(col1,col2,col3)这样的一个组合索引,那么相当于对col1列进行排序,也就是我们创建组合索引,以最左边的为准,只要查询条件中带有最左边的列,那么查询就会使用到索引

创建测试表

CREATE TABLE `student` (
 `id` int(11) NOT NULL,
 `name` varchar(10) NOT NULL,
 `age` int(11) NOT NULL,
 PRIMARY KEY (`id`),
 KEY `idx_id_name_age` (`id`,`name`,`age`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

填充100w测试数据

DROP PROCEDURE pro10;
CREATE PROCEDURE pro10()
BEGIN
	DECLARE i INT;
	DECLARE char_str varchar(100) DEFAULT 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
	DECLARE return_str varchar(255) DEFAULT '';
	DECLARE age INT;
	SET i = 1;
	WHILE i < 5000000 do
		SET return_str = substring(char_str, FLOOR(1 + RAND()*62), 8);
		SET i = i+1;
		SET age = FLOOR(RAND() * 100);
		INSERT INTO student(id, name, age) values(i, return_str, age);
	END WHILE;
END;

CALL pro10();

场景测试

EXPLAIN SELECT * FROM student WHERE id = 2;

可以看到该查询使用到了索引

EXPLAIN SELECT * FROM student WHERE id = 2 AND name = 'defghijk';

可以看到该查询使用到了索引

EXPLAIN SELECT * FROM student WHERE id = 2 AND name = 'defghijk' and age = 8;

可以看到该查询使用到了索引

EXPLAIN SELECT * FROM student WHERE id = 2 AND age = 8;

可以看到该查询使用到了索引

EXPLAIN SELECT * FROM student WHERE name = 'defghijk' AND age = 8;

可以看到该查询没有使用到索引,类型为index,查询行数为4989449,几乎进行了全表扫描,由于组合索引只针对最左边的列进行了排序,对于name、age只能进行全部扫描

EXPLAIN SELECT * FROM student WHERE name = 'defghijk' AND id = 2;

EXPLAIN SELECT * FROM student WHERE age = 8 AND id = 2;

EXPLAIN SELECT * FROM student WHERE name = 'defghijk' and age = 8 AND id = 2;

可以看到如上查询也使用到了索引,id放前面和放后面查询到的结果是一样的,MySQL会找出执行效率最高的一种查询方式,就是先根据id进行查询

总结

如上测试,可以看到只要查询条件的列中包含组合索引最左边的那一列,不管该列在查询条件中的位置,都会使用索引进行查询。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。

相关文章

  • 与MSSQL对比学习MYSQL的心得(八)--插入 更新 删除

    与MSSQL对比学习MYSQL的心得(八)--插入 更新 删除

    这一篇《与MSSQL对比学习MYSQL的心得(八)》将会讲解MYSQL的插入、更新和删除语句
    2014-08-08
  • mySQL中in查询与exists查询的区别小结

    mySQL中in查询与exists查询的区别小结

    最近被一个朋友问到mySQL中in查询和exists的区别,当然只是草草的回答了下,今天偶然看到了一篇关于mysql中的exists查询的文章,读完感觉太”冷落”它了,这里总结一下,也跟自己常用的in查询做一下对比。有需要的朋友们可以参考借鉴,下面来一起学习学习吧。
    2016-11-11
  • mysql批量删除大量数据

    mysql批量删除大量数据

    这篇文章主要介绍了mysql批量删除大量数据的相关资料,需要的朋友可以参考下
    2017-04-04
  • MySQL SELECT ...for update的具体使用

    MySQL SELECT ...for update的具体使用

    本文主要介绍了MySQL的SELECT ...for update的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-05-05
  • mysql索引篇explain命令详解

    mysql索引篇explain命令详解

    这篇文章主要介绍了mysql索引篇explain命令详解,mysql中的explain命令可以用来查看sql语句是否使用了索引,用了什么索引,有没有做全表扫描,更多相关内容需要的小伙伴可以参考一下
    2022-08-08
  • Ubuntu查看修改mysql的登录名和密码、安装phpmyadmin

    Ubuntu查看修改mysql的登录名和密码、安装phpmyadmin

    这篇文章主要介绍了Ubuntu查看修改mysql的登录名和密码、安装phpmyadmin,本文分步骤给大家讲解的非常详细,需要的朋友可以参考下
    2019-11-11
  • 分享8个不得不说的MySQL陷阱

    分享8个不得不说的MySQL陷阱

    这篇文章给大家分享8个不得不说的MySQL陷阱,非常不错,具有参考借鉴价值,需要的朋友参考下吧
    2018-03-03
  • MySQL和Oracle批量插入SQL的通用写法示例

    MySQL和Oracle批量插入SQL的通用写法示例

    当我们要往数据库中批量保存多条数据得时候,分不同数据库,有不同得插入方式,这篇文章主要给大家介绍了关于MySQL和Oracle批量插入SQL的通用写法的相关资料,需要的朋友可以参考下
    2021-11-11
  • 深入探究Mysql模糊查询是否区分大小写

    深入探究Mysql模糊查询是否区分大小写

    这篇文章主要给大家介绍了关于Mysql模糊查询是否区分大小写的相关资料,文中给出了5种解决方法以及各个方法的建议,需要的朋友可以参考下
    2021-06-06
  • 怎样快速开启MySQL的慢查询日志

    怎样快速开启MySQL的慢查询日志

    如果需要查看某一条SQL查询速度慢,并对慢的SQL进行优化,那么开启MySQL慢查询日志是一定要做的事情,本文介绍如何开启MySQL的慢查询日志,感兴趣的朋友跟随小编一起看看吧
    2023-11-11

最新评论