MySQL中复合聚集索引的实现
我需要创建复合聚集索引,比如:用户名、名称、id。实现这样的东西是真的吗?我需要提高查询的性能,比如where username=?名称=?通过在Innodb中使用聚集索引。但我认为它不会起作用,因为我的排名是第三位,而且它不会被使用。定义一个包含多列的聚集索引是可以的MySQL中复合聚集索引的实现,mysql,indexing,query-optimization,Mysql,Indexing,Query Optimization,我需要创建复合聚集索引,比如:用户名、名称、id。实现这样的东西是真的吗?我需要提高查询的性能,比如where username=?名称=?通过在Innodb中使用聚集索引。但我认为它不会起作用,因为我的排名是第三位,而且它不会被使用。定义一个包含多列的聚集索引是可以的 CREATE TABLE mytable ( username VARCHAR(64) NOT NULL, name VARCHAR(64) NOT NULL, id BIGINT PRIMARY KEY (us
CREATE TABLE mytable (
username VARCHAR(64) NOT NULL,
name VARCHAR(64) NOT NULL,
id BIGINT
PRIMARY KEY (username, name, id)
);
如果查询前两列,它将使用聚集索引,因此可以避免通过二级索引进行查找的开销
但是如果使用EXPLAIN报告优化器的查询计划,您将看到访问是type:ref
,这意味着索引查找,而不是唯一的索引查找。也就是说,它可能会匹配多行
mysql> explain select * from mytable where username = 'user' and name = 'name';
+----+-------------+---------+------------+------+---------------+---------+---------+-------------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+---------+------------+------+---------------+---------+---------+-------------+------+----------+-------+
| 1 | SIMPLE | mytable | NULL | ref | PRIMARY | PRIMARY | 516 | const,const | 1 | 100.00 | NULL |
+----+-------------+---------+------------+------+---------------+---------+---------+-------------+------+----------+-------+
在对主键执行查找时,我们希望看到type:eq\u ref
或type:const
,这意味着它正在执行唯一的查找,并且查询保证匹配0或1行
mysql> explain select * from mytable where username = 'user' and name = 'name' and id = 1;
+----+-------------+---------+------------+-------+---------------+---------+---------+-------------------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+---------+------------+-------+---------------+---------+---------+-------------------+------+----------+-------+
| 1 | SIMPLE | mytable | NULL | const | PRIMARY | PRIMARY | 524 | const,const,const | 1 | 100.00 | NULL |
+----+-------------+---------+------------+-------+---------------+---------+---------+-------------------+------+----------+-------+
两个查询都使用聚集索引
请回复您的评论:
InnoDB要求自动递增列是表中键的第一列。它不必是主键。因此,您可以这样做,例如:
CREATE TABLE `mytable` (
`username` varchar(64) NOT NULL,
`name` varchar(64) NOT NULL,
`id` bigint NOT NULL AUTO_INCREMENT,
`x` int DEFAULT NULL,
PRIMARY KEY (`username`,`name`,`id`),
KEY (`id`)
) ENGINE=InnoDB;
注意,我添加了一个额外的
键(id)
,以满足InnoDB的要求。但是在主键中,id
仍然在末尾。当我尝试在InnoDB中添加这样的键时:alter table user drop primary key,add primary key(用户名(12)、密码(4)、id);我收到一个错误:错误代码:1075。表定义不正确;只能有一个自动列,必须将其定义为键InnoDB要求自动递增列为键中的第一列。更正:“InnoDB要求自动递增列为某个键中的第一列。”@NoActualName-不要使用“前缀”((12)
,等等)。它破坏了索引的实用性。特别是,它不会超出第一个带前缀的列。请提供您的创建表
,这样我们就不必在各种边缘情况下跳舞了。