“x IS NULL”和“NOT(x IS NOT NULL)”之间有什么区别?

时间:2011-12-23 16:35:33

标签: sql ruby-on-rails postgresql arel

在postgresql的执行,性能或逻辑之间是否存在显着差异

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_clause将是arel_table[:deleted_at].not_eq(nil),但对于其他search_terms,它可以是各种子句,包括复合子句和子选择。将.not添加到结尾,arel将始终生成第二种形式的SQL。我可以生成第一个表单,通过特殊包装我的NULL检查并根据具体情况手动生成.eq.not_eq,但我想要一些明确的在我使代码更详细之前,这样做是有益的。

1 个答案:

答案 0 :(得分:7)

使用EXPLAIN查看差异(如果有)。

我认为查询重写器会对此进行优化,但我没有检查此示例的源代码。

编辑:我错了,根本没有优化。其中(“users”。“deleted_at”IS NULL)可以使用索引,(NOT(“users”。“deleted_at”IS NOT NULL))条件导致顺序磁盘扫描。