2013-06-19 178 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連接混用。它使你的查詢很難閱讀。

這些提示(除了最後一個提示之外)應該會加快查詢的速度,但它依然會很慢,這取決於數據量,硬件和負載。