2014-03-06 117 views
0

請我需要幫助。我有一個查詢我運行從兩個表中獲取數據,但它消耗大量內存,需要多達9秒才能獲取大約100條記錄。我可能需要在某個時候獲取高達20萬條記錄。請如何優化此查詢?MySQL左JOIN Group_concat性能問題

SELECT user_id AS id, name, address, phone, city, book_title 
    FROM users us LEFT OUTER JOIN 
    (SELECT bid, GROUP_CONCAT(DISTINCT book_title SEPARATOR ' ') 
    AS book_title FROM user_books GROUP BY bid)bo ON bo.bid = us.user_id 

在user_books表我有book_titles對一些用戶的多個條目,我想返回,其中包括所有的用戶都用的書名或不和一列內BOOK_TITLE結果。

我跑了一個SQL的查詢說明語句,並得到這個

id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra 
1  PRIMARY  us   ALL  NULL   NULL NULL  NULL 168272 
1  PRIMARY  <derived2> ALL  NULL   NULL NULL  NULL 65900 
2  DERIVED  user_books ALL  NULL   uid 4  NULL 164989 

注:我有列中標,BOOK_TITLE,USER_ID,姓名,地址,電話,城市各自的表中的索引。

有關如何提高性能的任何建議。

+0

bo.bid = u.user_id!?!?你確定? – Strawberry

+0

抱歉錯字錯誤bo.bid = us.user_id – andychukse

+0

稱爲bid的東西等於所謂的user_id。我很高興我不是DBA!?! – Strawberry

回答

1

爲什麼你需要創建派生表?爲什麼不這樣說:

SELECT 
user_id, name, address, phone, city, GROUP_CONCAT(DISTINCT book_title SEPARATOR ' ') book_title 
FROM 
users us 
LEFT OUTER JOIN user_books ub ON ub.bid = us.user_id 
GROUP BY us.user_id 
+0

與您的查詢它只提取只有book_title記錄的用戶 – andychukse

+0

好吧,它由us.user_id分組,有道理嗎? – avisheks

+1

是的,像魅力一樣工作!非常感謝 – andychukse

1

試試這個 - 比這裏給對方的回答更好的性能。這樣做可以避免在確定每個user_id的分組方面產生大量開銷,並且如果需要,您始終可以在用戶表中爲選擇添加WHERE子句。

SELECT 
*, 
    (SELECT GROUP_CONCAT(DISTINCT book_title SEPARATOR ' ') 
    FROM user_books ub 
    WHERE ub.bid=us.id 
) AS book_title 
FROM 
(SELECT user_id AS id, name, address, phone, city, book_title 
    FROM users 
) us 
+0

某些用戶沒有書籍記錄,這些用戶需要在查詢中返回,這種查詢會在這種情況下工作嗎? – andychukse

+0

嘿安迪 - 是的,它的確如此 - 當我第一次遇到解決方案時,我想知道這是另一個論壇上發佈的帖子的改編。我可以確認一個給定的用戶是否沒有書籍,那麼查詢中的派生字段'book_title'將只包含NULL。問候 –

+0

我做了我的本地主機上的一些測試,第一個答案返回結果比上述查詢更快。我不知道你是否有不同的情況。你能不能從你的最後表現出結果?第一個答案結果 - 顯示第0 - 29行(總計72個,查詢花費0.0013秒)|||| 以上答覆結果 - 顯示第0 - 29行(總計72個,查詢花費0.1015秒) – andychukse