每个InnoDB表都有一个聚簇索引 ,聚簇索引使用B+树构建,叶子节点存储的数据是整行记录。一般 情况下,聚簇索引等同于主键索引,当一个表没有创建主键索引时,InnoDB会自动创建一个ROWID字段来构建聚簇索引。InnoDB创建索引的具体规则如下:
1. 在表上定义主键 PRIMARY KEY , InnoDB 将主键索引用作聚簇索引。2. 如果表没有定义主键, InnoDB 会选择第一个不为 NULL 的唯一索引列用作聚簇索引。3. 如果以上两个都没有, InnoDB 会使用一个 6 字节长整型的隐式字段 ROWID 字段构建聚簇索 引。该ROWID 字段会在插入新行时自动递增。
除聚簇索引之外的所有索引都称为辅助索引。在中InnoDB,辅助索引中的叶子节点存储的数据是该行的主键值。在检索时,InnoDB使用此主键在聚簇索引中搜索行记录。
CREATE TABLE `t_user_innodb` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(20) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_age` (`age`) USING BTREE
) ENGINE=InnoDB;
主键索引
InnoDB要求表必须有一个主键索引,主键索引的叶子节点会存储数据行。
等值查询数据
select * from t_user_innodb where id=30
范围查询数据
select * from t_user_innodb where id between 30 and 49;
辅助索引
除聚簇索引之外的所有索引都称为辅助索引,InnoDB的辅助索引只会存储主键值而非磁盘地址。
以表t_user_innodb的age列为例,age索引的索引结果如下图:
等值查询数据
select * from t_user_innodb where age=22;
范围查询数据
组合索引
组合索引存储结构
表结构:
CREATE TABLE `t_multiple_index` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`a` int(11) DEFAULT NULL,
`b` int(11) DEFAULT NULL,
`c` varchar(10) DEFAULT NULL,
`d` varchar(10) DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_abc` (`a`,`b`,`c`)
) ENGINE=InnoDB;
查找方式
select * from t_multiple_index where a=13 and b=16 and c=4;
最左前缀匹配原则
最左前缀匹配原则和组合索引的索引存储结构和检索方式是有关系的。
组合索引创建原则
覆盖索引
前面我们提到,根据辅助索引树查询数据时,首先通过辅助索引找到主键值,然后需要再根据主键值到主键索引中找到主键对应的数据。这个过程称为回表。
但回表是否是必须的呢?当然不是必须的。
select中列数据,如果可以直接在辅助索引树上全部获取,也就是说索引树已经“覆盖”了我们的查询需求,这时MySQL就不会白费力气的回表查询,这中现象就是覆盖索引。使用explain工具查看执行计划,可以看到extra中“Using index”,代表使用了覆盖索引。
我们将查询语句修改为以下语句时,执行过程是什么样子呢?
SELECT a,b FROM t_multiple_index
索引条件下推ICP
mysql> show VARIABLES like 'optimizer_switch'\G;
#关闭ICP
SET optimizer_switch = 'index_condition_pushdown=off';
#开启ICP
SET optimizer_switch = 'index_condition_pushdown=on';
索引创建原则
目录