我在事务表上创建了一个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
暗示该索引已被实际使用。
那怎么可能?
答案 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)