【问题标题】:How to prevent MySQL selecting one index when a better one is available?当有更好的索引可用时,如何防止 MySQL 选择一个索引?
【发布时间】:2011-10-22 13:00:17
【问题描述】:

我有一个包含 30,000 行(并且还在增长)的表,我将它与另一个表连接起来。一些页面,我需要运行大约 100 多个这样的查询,事情变得很慢。如果我EXPLAIN 查询,我注意到一个表使用主键并且速度很快,但另一个表使用它的一个索引,这不是最好的。这是一个概述:

SIMPLE | acc_entries | ref | ledger,date,type,status,status_ledger_date_type | type | 1 | const | 15359 | Using where

这是一个示例查询:

SELECT SUM(usd) AS total FROM acc_entries
LEFT JOIN acc_ledgers ON acc_entries.ledger = acc_ledgers.id
WHERE acc_entries.status = 1 AND 
acc_ledgers.account = 3004 AND 
date >= '2011-01-01' AND 
date <= '2011-08-30' AND 
type = 'credit'

如您所见,我在 WHERE 字段中使用了 statusledger(与 acc_ledgers.account 连接的字段)、datetype。所有这些字段都有索引。但是,还有一个特定的索引以相同的顺序用于所有这些索引。它被称为status_ledger_data_type,如您所见,它是 MySQL 考虑使用的索引之一。然而,最后 MySQL 选择使用type 作为索引。这有大约 15,000 个可能的行(表的一半),而另一个组合索引仅包含其中的一小部分。所以我的问题是:为什么当有更好的索引可用时 MySQL 会选择这个索引,我该如何防止这种情况发生?

【问题讨论】:

    标签: mysql indexing query-optimization


    【解决方案1】:

    【讨论】:

      【解决方案2】:

      实际上,您希望索引基于较小的粒度。 Acc_Entries 表中的 Ledger 将在 ITS 的 ID 主索引上连接到 ACC_Ledgers 表,因此 Acc_Ledgers 并没有真正将 Ledger 部分用于 WHERE 子句。您的索引应与常见查询的 WHERE 子句尽可能匹配。在这种情况下,我会在

      上有一个索引

      (帐户、状态、类型、日期)

      Account 排在第一位的原因是较小的结果集。您可以有 5,000 个条目。其中,一个帐户帐户有 300 个条目,因此您已经消除了要处理的大量数据。然后,状态... 300,您可以有 100 @ 状态 1、100 @ 状态 2、100 @ 状态 3,所以您现在通过其他类型和日期标准进一步减少了集合等。

      否则您的查询完全没问题...只是个人写作风格,我尝试使用 WHERE 条件编写查询,因为它也以相同的顺序与索引紧密匹配,所以我只需要先使用 Account 子句,然后状态、类型和日期...但同样,这是编写查询的个人风格。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-04-04
        • 1970-01-01
        • 1970-01-01
        • 2016-12-10
        • 1970-01-01
        • 2019-04-26
        • 2015-05-17
        • 2015-03-24
        相关资源
        最近更新 更多