如果表具有多列索引,则优化器可以使用索引的任何最左边的前置符来查找行.例如,如果您对(col1,col2,col3)有三列索引,则您对(col1)、(col1,col2)和(col1,col2,col3)有索引搜索功能.
然而,我想知道使用此功能是否会带来任何性能损失.假设我有一个大表,存储用户看到 comments 的时间:
CREATE TABLE `comment_views` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) NOT NULL,
`comment_id` bigint(20) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `comment_views_comment_id_user_id_unique` (`comment_id`,`user_id`),
KEY `comment_views_user_id_foreign` (`user_id`),
CONSTRAINT `comment_views_comment_id_foreign` FOREIGN KEY (`comment_id`) REFERENCES `comments` (`id`),
CONSTRAINT `comment_views_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=38821916 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
通过在(comment_id
,user_id
)上指定复合键,并在user_id
上指定非复合键,我就可以使用最左边的前置规则进行comment_id
搜索.然而,如果只有comment_id
上有显式键,那么只指定comment_id
(即SELECT * FROM comment_views WHERE comment_id = 123
)的查找会更快吗?
如果复合键不唯一、列是字符串或列可为空,答案是否会改变?如果我使用范围、连接、依赖子查询、覆盖索引查询或其他索引访问怎么样?
我try 在有和没有额外索引的情况下运行EXPLAIN,除了显示我的新索引的possible_keys
之外,解释没有任何变化.事实上,EXPLAIN preferred似乎是复合密钥.也许是因为它在表定义中是第一个,或者它只是更喜欢唯一的键(尽管最左边的前置符并不唯一).我不知道我无法找到更多有关SQL实际上如何使用引擎盖下最左边的前置符的信息.