5

当我的查询使用 2 个字段的范围时,我试图找出如何为我的数据设计索引。

expenses_tbl:
idx        date     category      amount
auto-inc   INT       TINYINT      DECIMAL(7,2)
PK

列类别定义费用的类型。比如,娱乐、服装、教育等等。其他的栏目就很明显了。

我对该表的查询之一是查找在给定日期范围内费用超过 50 美元的所有实例。此查询将如下所示:

SELECT date, category, amount 
FROM expenses_tbl
WHERE date > 120101 AND date < 120811 
      AND amount > 50.00;

如何为此特定查询设计此表上的索引/二级索引。

假设:表格非常大(目前还没有,但这给了我学习的空间)。

4

3 回答 3

3

MySQL 通常不支持复合索引的多个部分的范围。它要么使用日期索引,要么使用金额索引,但不能同时使用两者。如果您有两个索引,每个索引一个,它可能会进行索引合并,但我不确定。

我会检查EXPLAIN添加这些索引之前和之后:

CREATE INDEX date_idx ON expenses_tbl (date);
CREATE INDEX amount_idx ON expenses_tbl (amount);

复合索引范围 - http://dev.mysql.com/doc/refman/5.5/en/range-access-multi-part.html

索引合并 - http://dev.mysql.com/doc/refman/5.0/en/index-merge-optimization.html

于 2012-08-11T21:59:36.773 回答
1

还有几点还没有提到:

索引中列的顺序可能会有所不同。您可能想尝试这两个索引:

(date, amount)
(amount, date)

选哪个?通常,您希望最具选择性的条件是索引中的第一列。

  • 如果您的日期范围很大,但很少有超过 50 美元的费用,那么您希望amount在索引中排在第一位。
  • 如果您的日期范围很窄,并且大部分费用超过 50 美元,那么您应该date首先考虑。
  • 如果两个索引都存在,那么 MySQL 将选择估计成本最低的索引。

您可以尝试添加两个索引,然后查看输出EXPLAIN SELECT ...以查看 MySQL 为您的查询选择的索引。


You may also want to consider a covering index. By including the column category in the index (as the last column) it means that all the data required for your query is available in the index, so MySQL does not need to look at the base table at all to get the results for your query.

于 2012-08-11T22:09:53.690 回答
0

您的问题的一般答案是您想要一个具有两个键的复合索引。第一个是日期,第二个是金额。

请注意,此索引将适用于对日期或日期和费用有限制的查询。它不适用于仅对费用有限制的查询。如果您同时拥有这两种类型,则可能需要第二个费用索引。

如果表非常非常大,那么您可能希望按日期对其进行分区,并在每个分区内建立索引。

于 2012-08-11T21:53:01.023 回答