MySQL中复合索引最左前缀与非复合索引性能是否一致?
MySQL复合索引最左前缀的性能疑问
MySQL官方文档指出:
若表存在多列索引,该索引的任意最左前缀均可被优化器用于查找行。例如,若您拥有(col1, col2, col3)三列索引,则您可基于(col1)、(col1, col2)和(col1, col2, col3)进行索引搜索。
我想了解使用这一特性是否存在性能损耗,以下是我的具体场景:
我有一张存储用户查看评论记录的大表,表结构如下:
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)复合索引来基于comment_id进行查询。但如果单独创建一个comment_id的单列索引,执行类似SELECT * FROM comment_views WHERE comment_id = 123的查询时,是否会比用复合索引的最左前缀更快?
另外还有几个延伸问题:
- 若复合索引不是唯一索引、列类型为字符串或列允许为空,上述结论是否会改变?
- 在范围查询、连接查询、相关子查询、覆盖索引查询或其他索引访问方式下,情况又会如何?
我自己做了测试:在有无单独comment_id索引的情况下执行EXPLAIN,除了possible_keys会显示新增的单列索引外,其他结果没有变化。而且优化器似乎更倾向于使用复合索引,可能是因为它在表定义中顺序靠前,或是优化器偏好唯一键(尽管这里的最左前缀并非唯一)。我不清楚MySQL底层是如何实现最左前缀索引使用的,也没找到更多相关信息。
内容的提问来源于stack exchange,提问作者jgawrych
相关产品推荐
相关产品推荐

