首先,这是我的查询:
SELECT
COUNT(*) as velocity_count,
SUM(`disbursements`.`amount`) as summation_amount
FROM `disbursements`
WHERE
`disbursements`.`accumulation_hash` = '40ad7f250cf23919bd8cc4619850a40444c5e90c978f88635a09ccf66a82ffb38e39ea51cdfd651b0ebdac5f5ca37cd7a17e0f60fea6cbce1397ccff5fa37346'
AND `disbursements`.`caller_id` = 1
AND `disbursements`.`active` = 1
AND (version_hash != '86b4111677294b27a1805643d193b8d437b6ddb170b4ed5dec39aa89bf070d160cbbcd697dfc1988efea8429b1f1557625bf956180c65d3dcd3a318280e0d2da')
AND (`disbursements`.`created_at` BETWEEN '2012-12-15 23:33:22'
AND '2013-01-14 23:33:22') LIMIT 1
解释扩展返回如下:
+----+-------------+---------------+-------+-----------------------------------------------------------------------------------------------------------------------------------------------+------------------------------+---------+------+--------+----------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+---------------+-------+-----------------------------------------------------------------------------------------------------------------------------------------------+------------------------------+---------+------+--------+----------+--------------------------+
| 1 | SIMPLE | disbursements | range | unique_request_index,index_disbursements_on_caller_id,disbursement_summation_index,disbursement_velocity_index,disbursement_version_out_index | disbursement_summation_index | 1543 | NULL | 191422 | 100.00 | Using where; Using index |
+----+-------------+---------------+-------+-----------------------------------------------------------------------------------------------------------------------------------------------+------------------------------+---------+------+--------+----------+--------------------------+
实际查询大约有 95,000 行。如果我解释另一个命中约 50 行的查询,则解释是相同的,只是估计的行数更少。
选择的索引按顺序包括累积哈希、调用者 ID、活动、版本哈希、创建时间、金额。
我尝试过使用 COUNT(id) 或 COUNT(caller_id),因为它们是非空字段并返回与 count(*) 相同的内容,但它对计划或运行时间没有任何影响的实际查询。
这也是一个很重的插入表,基本上每个查询自上次运行以来都会插入或更新一行,因此 mysql 查询缓存并不完全有用。
在我去使用 memcache 或 redis 之类的东西制作某种分桶时间序列缓存之前,是否有一个明显的解决方案可以让它更快地工作?正常的约 50 行查询在 5MS 内返回,超过 90k+ 行的查询需要 500-900MS,而我真的负担不起超过 100MS 的任何东西。
我应该指出日期是一个滚动的 30 天窗口,需要基本上是实时的。过期可能会以大约 1 分钟的粒度发生,但新项目需要在提交后立即看到。我也在RDS上,读取IOPS基本上是0,cpu大概是60-80%。当我不查询庞大的 90,000 多个记录项时,CPU 通常保持在 10% 以下。