Mysql Explain显示查询在不符合Mysql doc的情况下正在使用索引

时间:2019-05-31 09:46:14

标签: mysql indexing explain

我在事务表上创建了一个mysql多列索引。该索引使用3列,如我的rails模式中所述:

  add_index "merchant_transactions", ["reference", "parent_ref", "kind"], name: "by_reference_parent_ref_kind", using: :btree

现在我有此活动记录查询:

MerchantTransaction.where(reference: "2-9020", kind: "PLACE_BATCH")

在纯sql中给出的内容:

"SELECT `merchant_transactions`.* FROM `merchant_transactions` WHERE `merchant_transactions`.`reference` = '2-9020' AND `merchant_transactions`.`kind` = 'PLACE_BATCH'"

现在从我读到的有关mysql和多列索引的内容开始:

  

如果表具有多列索引,则该表的任何最左前缀   优化器可以使用index来查找行。例如,如果   您在(col1,col2,col3)上有一个三列索引,您已经建立了索引   (col1),(col1,col2)和(col1,col2,col3)的搜索功能。   有关更多信息,请see Section 8.3.5,“多列   索引”。

对我来说,这意味着先前查询不应该使用先前的索引。

但是,当我在MerchantTransaction.where(reference: "2-9020", kind: "PLACE_BATCH").explain列下的查询key上运行EXPLAIN时,我得到by_reference_parent_ref_kind,在Extra列下却有Using index condition暗示该索引已被实际使用。

那怎么可能?

2 个答案:

答案 0 :(得分:1)

它将使用索引,因为您在查询(reference)中列出了最左边的列,即文档中的用例(col1)。条件(kind)中的另一列不在索引中搜索。

答案 1 :(得分:0)

给予

WHERE reference = '...' AND kind = '...'

INDEX(reference, parent, kind)

优化器可以使用索引,但只能使用reference部分。

另一方面,如果查询中仅提到的那三列,则该索引为“覆盖”,因此优化程序还有另一个使用该索引的理由。

请提供EXPLAIN SELECT ...。在Key_len列中,它将暗示仅使用reference。在Extra列中,Using index是它正在“覆盖”的线索。

对于当前查询,这将是更好的索引,但对于其他一些查询,可能会更糟:

INDEX(reference, kind, parent)