如何有效地查询表而不影响实时事务

时间:2016-10-04 12:52:13

标签: mysql sql database

我有一个包含数百万条记录的高交易表,结构如下:

transaction
--------------
id             int
txn_status     varchar
amount         bigint
name           varchar
txn_time       datetime --Date and time of the transaction

txn_status字段值可以是completedPending。我需要运行一个查询来检索具有以下特征的记录数:

  1. 自最近15分钟以来与Pending txn_status的交易,(current_time - txn_time) <= 15 minutes
  2. 最后16到25分钟之间与Pending txn_status的交易,(current_time - txn_time) >= 16 minutes and (current_time - txn_time) <= 25 minutes
  3. 最后26到30分钟之间与Pending txn_status的交易,(current_time - txn_time) >= 26 minutes and (current_time - txn_time) <= 30 minutes
  4. Pending txn_status超过30分钟的交易,(current_time - txn_time) > 30 minutes
  5. 目前我脑子里有两种解决方案:

    1. 使用case语句每分钟查询生产数据库(case语句将根据上面的时间差过滤和分组记录)查询的where子句。 / p>

    2. 为避免对生产数据库施加太多负载,请使用具有类似表的单独数据库,并使用updateinsert触发器更新表并执行第1项中的查询之后在数据库上。

    3. 请在没有对数据库施加太多负担的情况下,如果有任何最佳或更好的解决方案,请分享。

3 个答案:

答案 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 - 它会对移动数据的管道进行排序,并且通常对性能更友好。