Mysql Query需要更多时间来执行?

时间:2013-06-19 13:45:18

标签: mysql mysql-workbench

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 workbench是我的查询需要13分钟才能执行,请建议我为所有相关列创建索引的最佳方法。

1 个答案:

答案 0 :(得分:1)

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

在这种情况下,您正在使用函数中的列值。因此,索引无法有效使用。

这样的表达效率非常低:

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连接混合使用。它使您的查询难以阅读。

这些提示(除了最后一个提示)应该可以加快查询速度,但它仍然可能很慢,具体取决于数据量,硬件和负载。