问:我的所有索引都会被使用吗?
答:极不可能。MySQL 更有可能选择一个单一的索引,一个具有最高选择性(消除最多行)的索引,然后从索引引用中访问数据页。
MySQL 可能会执行索引合并操作,但这将是罕见的例外。你真的需要做一个EXPLAIN
看看这是否正在发生,并做一些工作来开发一个 MySQL 将其视为最佳计划的案例。(可能有人已经完成了这项工作,并且有这样的测试用例。)
问:如果没有,如何实现。
A:你不想达到那个目的。您希望 MySQL 做的是生成一个最佳计划。索引合并计划很可能不是您查询的最佳计划。这样的操作需要 MySQL 将所有这些索引“匹配”在一起,这是一项繁重的工作。
问:多列索引会更好吗?
答:是的。您的特定查询的最佳索引是覆盖索引,它包括查询中引用的所有列。通常,您首先需要具有最高选择性和最高基数的列。您的查询似乎在进行范围扫描而不是相等性测试,您希望与列的整个值集相比,谓词中值范围最窄的列,首先在索引中。
问:如果我在 (id,userid,page) 上有一个多列索引,它会被使用吗?
答:可能。您在该索引的两个前导列上有范围扫描谓词,因此它绝对看起来像一个候选者。如果这些是您的查询中引用的唯一列,那么它更有可能使用索引。
您的查询文本中似乎对 create_time 的引用格式错误。看起来您打算在该列上有某种谓词。如果是这种情况,那么索引(id, userid, create_time)
将是更好的候选者,因为这样可以从索引中满足查询,而无需引用数据页。
另一方面,对数据页进行全面扫描可能是更理想的计划。
问:如果是这样,是否还会使用其他索引?
答:极不可能。MySQL 将在表上使用“多个”索引的想法是关于 MySQL 如何使用索引的常见误解。这不是不可能的,但 INDEX MERGE 操作不太可能是最佳计划。
问:如果我有一个包含所有列的多列索引,但我的查询不包含所有列,那么是否会使用该索引?
答:有可能。如果 MySQL 确定使用该索引是最佳计划,则将使用它。更有可能使用的索引(如果可用)是一个覆盖索引,它只包含查询中引用的列。