首页 > 解决方案 > 在 where 和 orderby 子句中使用两个单列索引

问题描述

我用谷歌搜索了很多,找不到我的问题的明确答案

假设我们有这个查询

SELECT * WHERE user_id = x ORDER BY date_created

如果我们在 user_id 上有一个单列索引,在 date_created 上有另一个,优化器是否使用这两个索引?还是只是 user_id 索引?

标签: mysqlsqlindexingquery-optimizationwhere-clause

解决方案


这是您的查询:

SELECT *
FROM mytable
WHERE user_id = 123 
ORDER BY date_created

如果您有两个不同的索引,那么 MySQL 可能会使用索引user_id来应用where谓词(如果它认为它将加快查询速度,这取决于数据的基数和其他因素)。它不会使用 上的索引date_created,因为它无法将满足where谓词的中间结果集与该索引相关联。

对于此查询,您需要在(user_id, date_created). 数据库使用索引中的第一个键来过滤数据集:在索引 B-tree 中,匹配的行已经按日期排序,因此该order by操作变为无操作。

我注意到您正在使用select *; 一般来说,这不是一个好习惯,也不利于性能。如果表中除了用户和日期之外还有其他列,这会迫使数据库在通过索引过滤和排序后查找表以带来相应的行,这可能比根本不使用索引更昂贵。如果您只需要几列,请枚举它们:

SELECT date_created, first_name, last_name 
FROM mytable
WHERE user_id = 123 
ORDER BY date_created

并在(user_id, date_created, first_name, last_name). 那是一个覆盖索引:数据库可以使用索引执行整个查询,而无需查找表本身。


推荐阅读