当查询必须处理大量行时,MySql性能会迅速降低

时间:2013-07-29 16:07:49

标签: mysql performance

我正在使用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.我的另一个想法(看起来很可能)是因为加入时间可以指数增长,即使连接不是基于输入日期。

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

感谢您的意见。

EXPLAIN的结果:

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"

1 个答案:

答案 0 :(得分:3)

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

  1. 索引
  2. 等待其他交易
  3. 内存约束
  4. 缓存问题
  5. 以下是我对每个人的看法:

    <强>索引

    我不认为它是一个完全缺失的索引,因为你以100倍的时间成本检索5倍以上的行。如果这是问题,那么缩放与行数或多或少是线性的。如果没有索引,如果查询优化是中等的,则缩放可能甚至优于1。但是,如果您有索引冲突,那么优化器会根据它认为最好的选择一个或另一个。优化器可能选择一个3-4秒,然后另一个300-400秒。

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

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

    等待他人

    如果其他事务正在修改数据,则可能会发生这种情况。尝试阅读uncommited,看看它是否加快。如果是这样,那么这就是你的问题。

    <强>内存

    当你的内存耗尽时,各种各样的事情会急剧减慢。查看1个月是否线性地缩放到2个月,如果1周线性缩放到.5周。

    <强>缓存

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