【问题标题】:Mysql Explain shows that query is using index when it shouldnt be according to Mysql docMysql Explain 显示查询在不应该根据 Mysql doc 的情况下使用索引
【发布时间】:2019-10-16 22:59:50
【问题描述】:

我在事务表上创建了一个 mysql 多列索引。该索引使用我的 rails 架构中描述的 3 列:

  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 和多列索引的内容:

如果表有一个多列索引,任何最左边的前缀 优化器可以使用索引来查找行。例如,如果 您在 (col1, col2, col3) 上有一个三列索引,您已编入索引 (col1)、(col1, col2) 和 (col1, col2, col3) 的搜索功能。 更多信息,see Section 8.3.5,“多列 索引”。

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

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

这怎么可能?

【问题讨论】:

    标签: mysql indexing explain


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      给定

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

      INDEX(reference, parent, kind)
      

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

      另一方面,如果查询中提到的唯一列是这三个列,则该索引是“覆盖”的,因此优化器有另一个理由使用该索引。

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

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

      INDEX(reference, kind, parent)
      

      【讨论】:

        猜你喜欢
        • 2021-10-09
        • 1970-01-01
        • 1970-01-01
        • 2014-11-04
        • 2012-08-06
        • 2013-06-17
        • 1970-01-01
        • 2019-10-30
        • 2016-06-11
        相关资源
        最近更新 更多