2012-07-26 58 views
0

我有一個需要很長時間才能執行的查詢。轉換表中約有35萬條記錄,trans_detail表中約有1萬條記錄。MySQL查詢優化 - 長時間運行查詢

我希望在優化查詢或數據庫結構方面有一些幫助。

查詢:

SELECT 
    DATE_FORMAT(t.utc_date_due, '%b %Y') AS date_trans, 
    LAST_DAY(t.utc_date_due) AS date_end, 
    SUM(td.amount * lode) AS 'amount', 
    SUM(t.amount_paid * lode) AS 'paid' 
FROM trans t 
LEFT JOIN trans_detail td ON t.id = td.trans_id AND td.ident = 'c' 
WHERE t.company_id = 1 
    AND (trans_type_id = 'inv' or trans_type_id = 'crn') 
    AND t.is_deleted = 0 
    AND t.is_draft = 0 
GROUP BY DATE_FORMAT(t.utc_date_due, '%b %Y') 
ORDER BY utc_date_due 

explain

+----+-------------+-------+-------------+----------------------------------------------------------+--------------------------------------+---------+----------------+------+-----------------------------------------------------------------------------------------------------+ 
| id | select_type | table | type  | possible_keys           | key         | key_len | ref   | rows | Extra                        | 
+----+-------------+-------+-------------+----------------------------------------------------------+--------------------------------------+---------+----------------+------+-----------------------------------------------------------------------------------------------------+ 
| 1 | SIMPLE  | t  | index_merge | fk_trans_company,fk_trans_trans_type,is_deleted,is_draft | fk_trans_company,is_draft,is_deleted | 4,1,2 | NULL   | 995 | Using intersect(fk_trans_company,is_draft,is_deleted); Using where; Using temporary; Using filesort | 
| 1 | SIMPLE  | td | ref   | fk_trans_detail_trans,ident        | fk_trans_detail_trans    | 4  | actester2.t.id | 1 |                          | 
+----+-------------+-------+-------------+----------------------------------------------------------+--------------------------------------+---------+----------------+------+-----------------------------------------------------------------------------------------------------+ 

回答

1

我想改變這一行開始:

AND (trans_type_id = 'inv' or trans_type_id = 'crn') 

使用IN子句:

AND (trans_type_id in ('inv', 'crn')) 
+0

這兩者是等價的,使用它們中的任何一個都沒有性能。 – 2012-07-26 15:33:06

+0

通常,但並非總是 - 取決於該字段是否已編制索引。 http://stackoverflow.com/questions/3074713/in-vs-or-in-the-sql-where-clause – Widor 2012-07-26 15:36:17

+0

+1。 thx爲鏈接。很高興知道,但索引列無關緊要。 – 2012-07-26 15:41:29

0

嘗試把

td.ident = 'c' 

您的WHERE子句。 您可以在utc_date_due上創建索引。

我個人建議,如果速度至關重要,使用兩步法,您應該使用一個臨時表並插入您的元素,然後只在臨時表上創建總和。