【发布时间】:2013-07-15 05:33:09
【问题描述】:
我有一个以 innodb 作为存储引擎的 MySQL 数据库,并且我有许多采用基本形式的查询:
SELECT bd.billing,
SUM(CASE WHEN tc.transaction_class = 'c' THEN bd.amount ELSE 0 END) AS charges,
SUM(CASE WHEN tc.transaction_class = 'a' THEN bd.amount ELSE 0 END) AS adjustments,
SUM(CASE WHEN tc.transaction_class = 'p' THEN bd.amount ELSE 0 END) AS payments,
SUM(bd.amount) AS balance_this_month
FROM billing_details bd
JOIN transaction_classes tc ON tc.transaction_code = bd.transaction_code
WHERE bd.entry_date BETWEEN '2013-06-04' AND '2013-07-01'
GROUP BY billing;
我正在尝试为采用这种形式的查询制定索引列的最佳策略。在我开始之前,只有单个列上的索引,并且解释显示正在读取 150 万行(正如您在此处看到的那样,只有一个月的数据量)。
我的第一次尝试将这个数字降低到 ~300,000,这是通过索引(entry_date、billing、transaction_code)实现的。在做了更多阅读(特别是高性能 MySQL)之后,我决定将 entry_date(通常是一个范围表达式)作为我最左边的列并不是最佳的,所以我尝试了(计费、事务代码、条目日期)并解释显示更像 4 -500,000 行。仍然比第一个数字有所改进,但随着我深入挖掘,我开始怀疑:
对于此类查询,我可以合理地期望从最佳索引中得到什么?我猜,因为我正在执行一个聚合函数,它总是会构建一个临时表并进行文件排序......或者是吗?我读得越多,我就越困惑。我的直觉是使用 entry_date 作为最左边的列,因为它是我的 where 子句中的唯一规定。更多的研究让我相信我应该把它放在最正确的位置,因为我正在查询一系列日期。但是我读到的只是真正谈论 where 子句——它只有 entry_date:这样的 sum/case 查询呢?我能否以有益的方式向该索引添加数量,或者除非我重新设计架构/查询,否则我会被我所拥有的东西所困扰吗?
【问题讨论】:
标签: mysql performance indexing innodb b-tree