该语句将使用哪个普通索引

Posted

技术标签:

【中文标题】该语句将使用哪个普通索引【英文标题】:Which ordinary index will this statement be used 【发布时间】:2020-08-13 23:45:06 【问题描述】:

给定下表:

CREATE TABLE `test` (
  `a` int(255) unsigned NOT NULL AUTO_INCREMENT,
  `b` varchar(64) NOT NULL DEFAULT '' ,
  `c` varchar(32) NOT NULL DEFAULT '' ,
  `d` varchar(32) NOT NULL DEFAULT '' ,
  PRIMARY KEY (`a`),
  KEY `b` (`b`) USING BTREE,
  KEY `c` (`c`(19)) USING BTREE,
  KEY `d` (`d`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='test';

insert test(a,b,c,d) values('1','1','1','1');
insert test(a,b,c,d) values('2','2','2','1');
insert test(a,b,c,d) values('3','3','3','1');
insert test(a,b,c,d) values('4','4','4','1');

我不知道下面的 SQL 使用哪个索引,但我知道 Innodb 引擎只使用一个索引。

explain select * from test where b='2' and c='2' and d='2';

我在mysql数据库中执行了上面的sql,然后这个语句使用'b index'。这里有什么规则吗?还是优化器有什么规则,但是这里用到了?

【问题讨论】:

【参考方案1】:

理论上,MySQL 会选择最严格的列上的索引——即选择最少行的那个。

但对于您的查询,您需要一个包含所有三列的索引,bcd,顺序不限。

【讨论】:

我不知道你所说的“普通”是什么意思。多列索引和单列索引一样“普通”。 谢谢大家。 .有人问我这个问题,我想了一个晚上。此表仅创建三个“普通”索引。是否有优化器来计算最严格和最少的行? @Eric 。 . . MySQL(如其他数据库)保留索引的统计信息。您可能想通过analyze 开始调查:dev.mysql.com/doc/refman/8.0/en/analyze-table.html 这个普通的索引好像(key b(b) using btree)。多列索引似乎(key inx_bcd (b,c,d) using btree)。【参考方案2】:

对于

where b='2' and c='2' and d='2';

INDEX(b,c,d) -- with the columns in any order

另一个问题。不要在没有充分理由的情况下使用“前缀”索引:

  KEY `c` (`c`(19)) USING BTREE,

基本上没用。

这里有一些指南:http://mysql.rjweb.org/doc.php/index_cookbook_mysql

【讨论】:

以上是关于该语句将使用哪个普通索引的主要内容,如果未能解决你的问题,请参考以下文章

sqlwhere后可以有多个条件后再嵌套吗

MySQL优化 SQL 语句的优化

哪个语句将成功调用该函数? [关闭]

mysql之普通索引和唯一索引

mysql在建表语句中添加索引

主键索引和普通索引的工作原理