0

我正在使用 MySql 并且遇到给定查询从交易表计算收入的情况。选定的交易可以跨越 1 天、1 周或 1 个月。

SELECT 
revenue formula 
FROM
    product inner join
    account on key_condition1 inner join
    transaction on key_condition2
WHERE
    tx.ENTRYDATE >= '2013-06-17 00:00:00' AND tx.ENTRYDATE < '2013-07-24 00:00:00'
GROUP BY product

当我为 where 语句提供一周时,查询将在 3-4 秒内运行。当我想要一个月的条目时,查询会在 300 - 400 秒内完成(如果有的话)。

我们正在使用的数据库非常大。它有大约 350 万笔交易。

起初我认为交易的绝对数量会导致这样的问题,但似乎并非如此。每周有 110363 个条目,每月有 576910 个条目。我的另一个想法(这似乎很可能)是,由于加入,即使加入不是基于进入日期,时间也会成倍增长。

我的问题是:连接是指数增长的“错误”吗?目前连接是不可避免的,但这可以通过一些数据库重构来解决。

感谢您的意见。

解释的结果:

id,select_type,table,type,possible_keys,key,key_len,ref,rows,Extra
1,SIMPLE,LOANPRODUCT,index,PRIMARY,PRIMARY,98,NULL,1,
1,SIMPLE,LOANACCOUNT,ref,"PRIMARY,LOANACCOUNT_PRODUCTTYPEKEY",LOANACCOUNT_PRODUCTTYPEKEY,99,LOANPRODUCT.ENCODEDKEY,16559,"Using where; Using index"
1,SIMPLE,LOANTRANSACTION,ref,"LOANTRANSACTION_PARENTACCOUNTKEY,LOANTRANSACTION_REVERSALTRANSACTIONKEY,LOANTRANSACTION_ENTRYDATE",LOANTRANSACTION_PARENTACCOUNTKEY,99,LOANACCOUNT.ENCODEDKEY,7,"Using where"
4

1 回答 1

3

这里可能有几个重要原因:

  1. 索引
  2. 等待其他交易
  3. 内存限制
  4. 缓存问题

以下是我对每一个的看法:

索引

我不认为这是一个完全缺失的索引,因为您以 100 倍的时间成本检索了 5 倍以上的行。如果这是问题所在,缩放将或多或少与行数成线性关系。在没有索引的情况下,如果查询优化一半不错,则缩放可能会比 1 还要好。但是,如果您有冲突的索引,那么优化器会根据它认为最好的选择一个或另一个。优化器很可能选择一个持续 3-4 秒,然后选择另一个持续 300-400 秒。

从您的 EXPLAIN 结果来看,您的索引似乎有冲突。我猜 LOANTRANSACTION_PARENTACCOUNTKEY 包含 key_condition2,而 LOANTRANSACTION_ENTRYDATE 包含 ENTRYDATE。两者都没有另一列。因此,优化器必须选择其中之一。您应该有一个包含两者的索引。我会把 ENTRYDATE 放在第一位。

我还猜测这个 EXPLAIN 来自较慢的查询,因为它没有使用 LOANTRANSACTION 上的索引来按 ENTRYDATE 过滤。因此,MySQL 需要读取所有这些行来查看它们是否在范围内。

等待别人

如果其他事务正在修改数据,则很可能出现这种情况。尝试阅读未提交的内容,看看它是否加快了速度。如果是这样,那么这是你的问题。

记忆

当你用完内存时,各种事情都会显着减慢。查看 1 个月是否线性扩展到 2 个月,以及 1 周是否线性扩展到 0.5 周。

缓存

如果您的数据不在缓存中,那么该数据将需要来自磁盘,与内存相比,这非常慢。这很可能是您的问题。如果您重新运行查询,第二次运行应该会明显更快。如果您的内存不足以包含相关行,那么您的查询将总是很慢。看看你的记忆是否应该能够容纳所有相关的表格。

于 2013-07-29T17:15:43.027 回答