我正在使用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"
答案 0 :(得分:3)
这里可能有几个重要原因:
以下是我对每个人的看法:
<强>索引强>
我不认为它是一个完全缺失的索引,因为你以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周。
<强>缓存强>
如果您的数据不在缓存中,那么该数据将需要来自磁盘,这与内存相比非常慢。这很可能是你的问题。如果重新运行查询,第二次运行应该明显加快。如果您的内存不足以包含相关行,那么您的查询将始终很慢。看看你的记忆是否能够容纳所有相关的表格。