2012-05-15 161 views
2

我看到SELECT EXISTS用了很多,如:SELECT EXISTS與LIMIT 1

if db.query(""" 
     SELECT EXISTS (
      SELECT 1 FROM checkout 
      WHERE checkout_id = %s 
     ) 
    """ % checkout_id).getresult()[0][0] == 't': 

與我喜歡:

if db.query(""" 
     SELECT 1 FROM checkout 
     WHERE checkout_id = %s 
     LIMIT 1 
    """ % checkout_id).getresult(): 

哪一個更好呢?

P.S.我正在使用Python和PosgreSQL。

cert=> explain SELECT EXISTS (SELECT 1 FROM checkout WHERE checkout_id = 3); 
             QUERY PLAN          
-------------------------------------------------------------------------------------- 
Result (cost=4.03..4.03 rows=1 width=0) 
    InitPlan 
    -> Index Scan using checkout_pkey on checkout (cost=0.00..4.03 rows=1 width=0) 
      Index Cond: (checkout_id = 3) 
(4 rows) 

cert=> explain SELECT 1 FROM checkout WHERE checkout_id = 3 limit 1; 
            QUERY PLAN          
------------------------------------------------------------------------------------ 
Limit (cost=0.00..4.03 rows=1 width=0) 
    -> Index Scan using checkout_pkey on checkout (cost=0.00..4.03 rows=1 width=0) 
     Index Cond: (checkout_id = 3) 
(3 rows) 

我的觀點是,爲什麼從結果得到一個行和檢查它是否是第一列是真的,如果我可以檢查是否有任何行所有,這意味着相同的?

+0

您正在使用哪些DBMS? –

+0

絕對不是SQL Server。 LIMIT 1告訴我這可能是mysql(只是猜測) – Alex

+0

PostgreSQL爲這兩個版本生成(幾乎)相同的執行計劃。所以他們之間不應該有區別 –

回答

2

PostgreSQL似乎足夠聰明地處理這兩個陳述,就像你可以在執行計劃中清楚看到的一樣。

我與當地表測試〜15萬行〜100條件選拔出來的也表現出相同的行爲

的底線是:它並沒有真正不管你使用哪一個,但你應該意識到其他DBMS可能不會以相同的方式運行。

1

當您使用EXPLAIN時,您可以看到第一條語句將執行額外的子查詢,而第二條語句不會執行額外的子查詢。

這就是爲什麼我寧願使用limit代替exists

例子:

explain SELECT EXISTS (SELECT 1 FROM checkout WHERE id = 3); 
explain SELECT 1 FROM checkout WHERE id = 3 limit 1; 
+0

這很不禮貌,你總是指定一個sunquery來檢查行的存在性。文件本身說'指定一個子查詢來測試行的存在' – Rahul

6

就我的第二個說法是,如果條件不滿足就不會返回一行有問題。

+0

這確實是一個真實的陳述。 – Rahul

+0

我不知道這是嵌入在(php?)中的過程語言,所以db.query可能會引發異常。 –

+0

非常好的捕獲 –