我有一个包含数百万条记录的高交易表,结构如下:
transaction
--------------
id int
txn_status varchar
amount bigint
name varchar
txn_time datetime --Date and time of the transaction
txn_status
字段值可以是completed
或Pending
。我需要运行一个查询来检索具有以下特征的记录数:
Pending txn_status
的交易,(current_time - txn_time) <= 15 minutes
Pending txn_status
的交易,(current_time - txn_time) >= 16 minutes and (current_time - txn_time) <= 25 minutes
Pending txn_status
的交易,(current_time - txn_time) >= 26 minutes and (current_time - txn_time) <= 30 minutes
Pending txn_status
超过30分钟的交易,(current_time - txn_time) > 30 minutes
目前我脑子里有两种解决方案:
使用case
语句每分钟查询生产数据库(case语句将根据上面的时间差过滤和分组记录)查询的where
子句。 / p>
为避免对生产数据库施加太多负载,请使用具有类似表的单独数据库,并使用update
和insert
触发器更新表并执行第1项中的查询之后在数据库上。
请在没有对数据库施加太多负担的情况下,如果有任何最佳或更好的解决方案,请分享。
答案 0 :(得分:2)
如果你有适当的索引,即复合索引INDEX(txn_status, txn_time)
如果表中的大多数行都没有待处理,那么这样的查询应该非常快:SELECT * FROM transaction WHERE txn_status = 'pending' AND txn_time < NOW() - INTERVAL 30 MINUTE
因为非待定行的数量不应该真正影响查询的速度
答案 1 :(得分:2)
如果您有表格索引
CREATE INDEX txn_status_time ON transaction (txn_status, txn_time DESC)
以一种比较txn_time而不算算的方式编写查询,那么你的查询会非常快速
类似的东西:
SELECT
COUNT(*),
CASE WHEN txn_time >= current_time - 15 mins THEN "last 15" ... END
FROM transaction
GROUP BY CASE WHEN txn_time >= current_time - 15 mins THEN "last 15" ... END
答案 2 :(得分:0)
首先 - 最好的解决方案通常是最简单的。看看您是否可以在生产数据库上执行查询而不会造成过度的性能问题;通过添加索引来调整这些查询。 &#34;数百万条记录&#34;只要你有良好的索引和查询来达到这些索引,就不是什么大问题。
我建议不要使用选项2.我通常反对以这种方式使用触发器,因为它们可能导致不可预测的行为,包括不可预测的性能问题。如果您的更新&#34;触发器开始运行缓慢,它也会影响您的生产数据库;只需要开发人员意外删除报表数据库中的索引,您的生产系统就会变慢并变得无法使用。
相反,考虑replication - 它会对移动数据的管道进行排序,并且通常对性能更友好。