2011-05-24 64 views
0

在這個SQL:MySQL查詢中LEFT慢得令人難以置信JOIN如果給定值0到主ID

SELECT s.*, 
      u.id, 
      u.name 
     FROM shops s 
LEFT JOIN users u ON u.id = s.user_id 
        OR u.id = s.owner_user_id 
    WHERE s.status = 1 

出於某種原因,這個查詢需要一個神奇的時代。儘管id是主鍵。它似乎特別是在我添加這部分OR u.id=s.owner_user_id查詢變得緩慢。 owner_user_id往往只有0幾次。但爲什麼顯然掃描整個桌子需要很長時間?數據庫表users非常長。我沒有設計它。這對於後來的程序員添加了太多字段的客戶而言。桌子是22k行和幾十個領域。

*僅用於演示的字段名稱。實際名稱是不同的,所以不要問我爲什麼要找owner_user_id(;我通過刪除「OR ...」部分來解決緩慢問題,而是在循環中搜索id,如果它不是0。但我想知道爲什麼發生這種情況以及如何加速比該查詢原樣。

+1

「數據庫表用戶非常長大」 - 22k行不大;它很小! – 2011-05-24 02:15:24

+0

好吧,有幾十個未優化的領域。 – 2011-05-24 02:23:33

+0

的邏輯是要沿着與商店相關的用戶信息獲取商店列表,商店可以有一個或另一個兩個用戶。 *我編輯了選擇部分。 – 2011-05-24 02:36:50

回答

1

您可以通過使用IN代替OR加快步伐但這是次要的。

SELECT u.id, 
      u.name 
     FROM shops s 
LEFT JOIN users u ON u.id IN (s.user_id, s.owner_user_id) 
WHERE s.status = 1 

首先,是在這個表上有任何索引?主要一個在user.id字段或s.user_id或s.owner_user_id?

不過,我必須爲k爲什麼您需要使用LEFT JOIN而不是常規連接。 LEFT JOIN導致每一行與每一行匹配。由於我假定值/ id應該在user_id或owner_user_id字段中,並且總是會有匹配,如果是這種情況,那麼使用JOIN應該會加快查詢的速度。

而且米奇說,22K行很小。

+0

謝謝,這是一個很好的建議,我會測試。如果沒有匹配,我確實使用了LEFT JOIN,但是之前我在之前添加了OR部分之前,我應該已經返回了使用內部連接,但是您能否詳細說明「LEFT JOIN導致每行匹配每隔一個「。我認爲LEFT JOIN和INNER JOIN完全一樣,只是不需要匹配。也許這是我的問題。如果考慮到數十個未經優化的雜亂領域,22k並不算小。 user_id和owner_user_id上已經有一個索引。而你。ID是主鍵。 – 2011-05-24 03:00:42

0

你打算怎麼知道哪個用戶記錄是哪個?以下是我會做它

SELECT s.*, 
     u.name AS user_name, 
     o.name AS owner_name 
FROM shops s 
LEFT JOIN users u ON s.user_id = u.id 
LEFT JOIN users o ON s.owner_user_id = o.id 
WHERE s.status = 1 

我省略了從用戶表的ID在SELECT作爲s.*這將是部分反正。

我很好奇左側加入了。如果shops.user_idshops.owner_user_id是必需的外鍵,請改用內連接。

+0

謝謝,在我的情況下,我不需要知道哪個用戶記錄是哪個。因爲在這種情況下user_id或owner_user_id不能同時爲兩者。我同意關於左連接感謝您的提示,但現在我的問題爲什麼左連接會比內連接慢。 – 2011-05-24 03:03:50