当我的查询使用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;
如何针对此特定查询在此表上设计索引/二级索引。
假设:表格非常大(目前不是,但这给了我一个学习的空间)。
答案 0 :(得分: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
答案 1 :(得分:1)
还有一些尚未提及的要点:
索引中列的顺序可以有所不同。您可能想要尝试这两个索引:
(date, amount)
(amount, date)
选哪个?通常,您希望最多选择性条件成为索引中的第一列。
amount
。date
。您可以尝试添加两个索引,然后查看EXPLAIN SELECT ...
的输出,以查看MySQL为您的查询选择的索引。
您可能还想考虑覆盖索引。通过在索引中包含列category
(作为最后一列),这意味着您的查询所需的所有数据都可以在索引中使用,因此MySQL根本不需要查看基表来获取查询结果。
答案 2 :(得分:0)
您的问题的一般答案是您需要一个带有两个键的复合索引。第一个是日期,第二个是金额。
请注意,此索引适用于对日期或日期以及费用有限制的查询。它仅适用于仅限于费用的查询。如果您同时拥有这两种类型,则可能需要花费第二个索引。
如果表真的非常大,那么您可能希望按日期对其进行分区,并在每个分区内按费用构建索引。