2011-12-23 83 views
4

是否有PostgreSQL的交易執行,業績「x IS NULL」和「NOT(x IS NOT NULL)」之間的區別是什麼?

SELECT "users".* FROM "users" WHERE ("users"."deleted_at" IS NULL) 

SELECT "users".* FROM "users" WHERE (NOT ("users"."deleted_at" IS NOT NULL)) 

顯然之間的顯著差異,或者邏輯,如果用手寫,第一個表達式是一個我會寫(誰也故意寫出雙重否定?!)。但是,在這種情況下,我使用Ruby的AREL庫動態創建兩個版本,有點像這樣:

def generate_query(search_terms, negated=false, users=User) 
    where_clause = arel_for_one_of_many_possible_queries(search_terms) 
    where_clause = where_clause.not if negated 
    users.where(where_clause) 
end 

而且,對於"deleted" SEARCH_TERM,該where_clausearel_table[:deleted_at].not_eq(nil),但對於其他SEARCH_TERMS它可能是各種條款,包括複合條款和子選擇。將.not添加到最後,arel將始終生成第二種形式的SQL。我可能生成第一種形式的特殊框我的NULL檢查和手動生成.eq.not_eq視情況而定,但我希望有一些明確的好處,在我做我的代碼更詳細之前。

+1

兩個WHERE子句產生完全相同的結果。無功能差異。但是,查詢計劃程序可能無法在表達式上使用其他適合的索引,如果您應該使用該索引。 –

回答

7

使用EXPLAIN查看區別,如果有的話。

我認爲查詢重寫器會優化這個,但我沒有檢查這個例子的源代碼。

編輯:我錯了,這根本沒有優化。其中(「users」,「deleted_at」爲NULL)可以使用索引,(NOT(「users」,「deleted_at」IS NOT NULL))條件導致順序磁盤掃描。

+0

糟糕。顯然我應該檢查'解釋'!謝謝。但是,只是爲了使事情清楚,兩者之間沒有任何邏輯*不同,對嗎?我有時會忘記確切的SQL關係代數規則是用於處理NULL相等的,這可能會導致一些不幸的意外。 –

+0

FWIW,postgresql 8.4.9的查詢重寫器似乎沒有爲我重寫。所以我需要用生產數據來測試它,看看它是否會產生顯着的性能差異。 –

+0

你能告訴我們兩個查詢計劃之間的區別嗎? –

相關問題