まず、これが私が持っているクエリです:
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
Explainextendedは次を返します。
+----+-------------+---------------+-------+-----------------------------------------------------------------------------------------------------------------------------------------------+------------------------------+---------+------+--------+----------+--------------------------+
| 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行に達する別のクエリを説明する場合、説明は同じですが、推定される行が少なくなります。
選択されるインデックスは、accumulation_hash、caller_id、active、version_hash、created_at、amountの順でカバーされます。
COUNT(id)またはCOUNT(caller_id)はnull以外のフィールドであり、count(*)と同じものを返すため、試してみましたが、計画や実行時間には影響しません。実際のクエリの。
これも重い挿入テーブルです。基本的に、すべてのクエリで最後に実行されてから行が挿入または更新されているため、mysqlクエリキャッシュが完全に役立つわけではありません。
memcacheやredisなどを使用してバケット化されたタイムシーケンスキャッシュを作成する前に、これをはるかに高速に動作させるための明らかな解決策はありますか?通常の約50行のクエリは5MSで返され、90k以上の行にまたがるクエリは500〜900MSを使用しており、100MSを超えると実際には何も買う余裕がありません。
日付は、本質的にリアルタイムである必要がある30日間のローリングウィンドウであることを指摘する必要があります。有効期限はおそらく1分程度の粒度で発生する可能性がありますが、コミットするとすぐに新しいアイテムを確認する必要があります。私もRDSを使用しており、Read IOPSは基本的に0であり、CPUは約60〜80%です。巨大な90,000以上のレコードアイテムをクエリしていないとき、CPUは通常10%未満にとどまります。