2013-06-19 179 views
0
SELECT BB.NAME BranchName,VI.NAME Village,COUNT(BAC.CBSACCOUNTNUMBER) "No.Of Accounts", 
SUM(BAC.CURRENTBALANCE) SumOfAmount, 
SUM(CASE WHEN transactiontype = 'C' THEN amount ELSE 0 END) AS CreditTotal, 
SUM(CASE WHEN transactiontype = 'D' THEN amount ELSE 0 END) AS DebitTotal, 
SUM(CASE WHEN transactiontype = 'C' THEN amount WHEN transactiontype = 'D' THEN -1 * amount ELSE 0 END) AS CurrentBalance 
FROM CUSTOMER CU,APPLICANT AP,ADDRESS AD,VILLAGE VI,BANKBRANCH BB,BANKACCOUNT BAC 
LEFT OUTER JOIN accounttransaction ACT ON ACT.BANKACCOUNT_CBSACCOUNTNUMBER=BAC.CBSACCOUNTNUMBER 
AND DATE_FORMAT(ACT.TRANDATE,'%Y-%m-%d')<='2013-05-09' 
AND DATE_FORMAT(BAC.ACCOUNTOPENINGDATE,'%Y-%m-%d') <'2013-05-09' 
AND ACT.BANKACCOUNT_CBSACCOUNTNUMBER IS NOT NULL 
WHERE CU.CODE=AP.CUSTOMER_CODE AND BAC.ENTITY='CUSTOMER' AND BAC.ENTITYCODE=CU.CODE 
AND AD.ENTITY='APPLICANT' AND AD.ENTITYCODE=AP.CODE 
AND AD.VILLAGE_CODE=VI.CODE AND VI.STATE_CODE=AD.STATE_CODE AND VI.DISTRICT_CODE=AD.DISTRICT_CODE 
AND VI.BLOCK_CODE=AD.BLOCK_CODE AND VI.PANCHAYAT_CODE=AD.PANCHAYAT_CODE 
AND CU.BANKBRANCH_CODE=BB.CODE AND BAC.CBSACCOUNTNUMBER IS NOT NULL AND ACT.TRANSACTIONTYPE IS NOT NULL 
GROUP BY BB.NAME,VI.NAME LIMIT 10; 

and 

below is my explain plan 

id select_type table type possible_keys key key_len ref rows Extra 
1 SIMPLE AD index ADDRESS_ENTITYCODE ADDRESS_ENTITYCODE 598 NULL 47234 Using where; Using index; Using temporary; Using filesort 
1 SIMPLE VI ref PRIMARY PRIMARY 62 fiserveraupgb.AD.VILLAGE_CODE 1 Using where 
1 SIMPLE AP eq_ref PRIMARY,AppCodeIndex PRIMARY 62 fiserveraupgb.AD.ENTITYCODE 1 
1 SIMPLE BAC ref BANKACCOUNT_ENTITYCODE BANKACCOUNT_ENTITYCODE 63 fiserveraupgb.AP.CUSTOMER_CODE 1 Using where; Using index 
1 SIMPLE CU eq_ref PRIMARY,CustCodeIndex PRIMARY 62 fiserveraupgb.AP.CUSTOMER_CODE 1 
1 SIMPLE BB ref PRIMARY,Bankbranch_CodeName PRIMARY 62 fiserveraupgb.CU.BANKBRANCH_CODE 1 
1 SIMPLE ACT index NULL accounttransaction_sysidindes 280 NULL 22981 Using where; Using index; Using join buffer 

Mysql服务器版本5.5和我正在使用下面的mysql工作台是我的查询它需要13分钟执行,请建议最好的方法,我已经创建了涉及所有列的索引。Mysql查询需要更多时间执行?

回答

1

您主要需要在连接和where子句中使用的列的索引。其他索引不会为您的选择语句增加值,并会降低插入和更新速度。

在这种情况下,您正在使用函数中的列值。由于这个原因,索引不能有效使用。

像这样的表达式是非常低效的:

DATE_FORMAT(ACT.TRANDATE,'%Y-%m-%d')<='2013-05-09' 

它会产生很多字符串转换的,因为所有的TRANDATES转化成它们的值的字符串表示。这些值需要临时存储并且没有索引,因此除了转换之外,不再使用ACT.TRANDATE上的任何索引。这可能会导致在解释计划结束时使用相当昂贵的“使用加入缓冲区”。

而是将字符串'2013-05-09'转换为日期值,并将此值用作查询中的常量或参数。

要做的另一件事是为单独的列创建不是单独的索引,而是在where和/或join中使用的一组列的索引。例如,这部分:

AD.ENTITY = 'APPLICANT' AND 
AD.ENTITYCODE = AP.CODE AND 
AD.VILLAGE_CODE = VI.CODE 

具有在列ENTITY,ENTITYCODE一个索引,并且VILLAGE_CODE一起会比具有用于它们中的每一个单独的索引更有效。这也可能有助于包括其他栏目。

最后一项:如果某列或列的组合保证是唯一的,请添加一个唯一索引。它在选择上稍快。

一般建议:不要将旧连接语法与ansi连接混用。它使你的查询很难阅读。

这些提示(除了最后一个提示之外)应该会加快查询的速度,但它依然会很慢,这取决于数据量,硬件和负载。