2012-02-04 46 views
4

我希望這個問題沒有被問到,我試圖尋找類似的問題,但可能使用了錯誤的關鍵字。總之,我碰到一個情況,我必須尋找誰從來沒有下訂單的客戶,所以在查詢運行這樣的:改善選擇不在

SELECT * FROM customers 
where customers_id NOT IN (SELECT customers_id FROM orders) 

我看,這是不好的嵌套SELECT S,所以什麼是更好的選擇?

此外,我應該做select *還是應該指定字段,我還在某個地方看過,最好是select *

謝謝大家提前。

+0

看到的答案後,我有一個疑問EXISTS的優化。你可以請時間StilesCrisis和Joop Eggen的解決方案,看看哪一個跑得更快?感謝 – 2012-02-04 08:03:21

+1

礦:顯示行0 - 29(5390總計,查詢花費0.0155秒) StilesCrisis:顯示行0 - 29(5390總計,查詢花費0.0090秒) 喬普埃根:顯示行0 - 29(5390總共查詢花費0.0039秒) 注:我每跑一次,可能需要運行多次獲得平均時間的權利。此外,對於喬普的一個我用SELECT *,想知道如果事情可以改善,如果我不與特定的字段 – mr1031011 2012-02-04 08:35:48

+1

選擇不管你相信與否,之後多次運行喬普的答案仍然是在我的情況下更快。 – mr1031011 2012-02-04 08:39:36

回答

5
SELECT * FROM customers 
LEFT JOIN orders ON customers.customers_id = orders.customers_id 
WHERE orders.customers_id IS NULL 
+0

親愛的StilesCrisis,謝謝你的答案,非常有趣的解決方案,從來沒有想過它 – mr1031011 2012-02-04 08:46:03

2

容易的問題:SELECT *比選擇一些領域更加昂貴,它可以是戲劇性的。數據較少,如果索引中的所有字段都沒有表訪問。沒有從數據庫字段值到編程語言變量的編組。

嵌套子查詢和關節有他們的權利。

SELECT * 
FROM customers c 
WHERE NOT EXISTS(SELECT * 
       FROM orders o 
       WHERE o.customers_id = c.customers_id) 

MySQL的說,它可以更好地優化形式存在遞歸優化上c.customers_id選擇現在擁有的信息:

SELECT * FROM customers where customers_id NOT IN (SELECT customers_id FROM orders) 

可以作爲被改寫。

雖然最好是@StilesCrisis的加入,但我懷疑它是正確的。 (雖然我一天沒喝我的第一杯咖啡。)

順便說一句。 EXISTS(SELECT *並不是真的爲所有領域預留空間,並且沒關係。

+1

不知道你爲什麼懷疑'JOIN'。這並不複雜。 – StilesCrisis 2012-02-04 07:50:10

+0

現在有一個** **加入對customers_id但你想去的地方存在_no_這樣的匹配的客戶。空檢查不影響。是嗎? NOOO你是對的。 – 2012-02-04 08:03:25

+0

@StilesCrisis也許'選擇DISTINCT'?必須說,從來沒有使用過你的圖案,儘管類似的左側關節 – 2012-02-04 08:17:23