2013-05-04 55 views
0

我在執行多個連接的查詢時遇到困難,而且對於大型記錄集非常慢。下面是該查詢:優化使用concat按順序排列的慢查詢

SELECT 
    order_headers.*, 
    SUM(order_details.cost) AS amount, 
    CONCAT(organizations.card_first_name, 
      ' ', 
      organizations.card_last_name) AS card_name 
FROM 
    order_headers 
     INNER JOIN 
    organizations ON order_headers.organization_id = organizations.id 
     LEFT JOIN 
    order_details ON order_details.order_header_id = order_headers.id 
     LEFT JOIN 
    user_accounts ON user_accounts.organization_id = organizations.id 
     AND organizations.is_single_user = 1 
WHERE 
    (status IN ('UNCHARGED' , 'ERROR')) 
GROUP BY order_headers.id 
HAVING SUM(order_details.cost) > 0 
ORDER BY IF(organizations.is_single_user = 1, 
    (user_accounts.first_name + ' ' + user_accounts.last_name), 
    organizations.name) ASC 
LIMIT 100 OFFSET 0 

有幾件事情,我可以從查詢中刪除(儘管需要爲我的應用程序的功能),即加快查詢到〜0.183秒。其中包括:

  1. 完全刪除order by子句。由於某些原因,MySQL不喜歡 從user_accounts表中拉入字段。但這意味着我無法按姓名排序。僅僅刪除連接是不夠的,我必須先刪除order子句中的第一個AND last,以獲得任何性能增益。我考慮過的一個選項是「緩存」users.name字段中的用戶名/姓。但是,僅運行organizational.name的查詢排序也是非高性能的。我不得不重構我的應用程序代碼。
  2. 刪除所有參考資料,包括order_details表(這 實際上是我們最大的表約101K記錄)。但之後我沒有訂單明細的總和,並且我沒有將結果限制爲sum> 0的那些order_headers。

任何幫助都非常感謝。

回答

0

首先,您有條件ORDER BY子句似乎是不必要的。您在user_accounts上的JOIN僅指定organizations,其中is_single_user = 1。但是你使用它作爲你的條件的一部分。在這種情況下,is_single_user = 1將始終爲真。

那麼試試這個修訂ORDER BY條款:

SELECT 
    order_headers.*, 
    SUM(order_details.cost) AS amount, 
    CONCAT(organizations.card_first_name, 
      ' ', 
      organizations.card_last_name) AS card_name 
FROM 
    order_headers 
     INNER JOIN 
    organizations ON order_headers.organization_id = organizations.id 
     LEFT JOIN 
    order_details ON order_details.order_header_id = order_headers.id 
     LEFT JOIN 
    user_accounts ON user_accounts.organization_id = organizations.id 
     AND organizations.is_single_user = 1 
WHERE 
    (status IN ('UNCHARGED' , 'ERROR')) 
GROUP BY order_headers.id 
HAVING SUM(order_details.cost) > 0 
ORDER BY user_accounts.first_name, user_accounts.last_name 
LIMIT 100 OFFSET 0 

二,請確保您有建立在您所有的外鍵索引(你要加入的那些),也許對user_accounts.first_name + user_accounts.last_name幫助排序。

+0

這是一個左連接,所以組織仍然包含is_single_user = 0。 – 2013-05-04 07:14:35