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 分钟才能执行,请建议我为所涉及的所有列创建索引的最佳方法。

4

1 回答 1

1

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

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

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

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

它会导致大量的字符串转换,因为所有的 TRANDATES 都被转换为其值的字符串表示形式。这些值需要临时存储并且没有索引,因此除了转换之外,不再使用 ACT.TRANDATE 上的任何索引。这可能会导致在解释计划结束时出现相当昂贵的“使用连接缓冲区”。

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

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

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

在 ENTITY、ENTITYCODE 和 VILLAGE_CODE 列上设置一个索引比为每个列设置一个单独的索引更有效。它也可能有助于包括其他列。

最后:如果保证一列或列组合是唯一的,则添加唯一索引。选择时稍快一些。

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

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

于 2013-06-19T13:51:30.757 回答