“x IS NULL”和“NOT(x IS NOT NULL)”有什么区别?
·
问题:“x IS NULL”和“NOT(x IS NOT NULL)”有什么区别?
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"
搜索_term,where_clause
将是arel_table[:deleted_at].not_eq(nil)
,但对于其他搜索_term,它可能是各种子句,包括复合子句和子选择。将.not
添加到末尾,arel总是会生成第二种形式的SQL。我_可以_通过特殊封装我的NULL
检查并根据具体情况手动生成.eq
或.not_eq
来生成第一个表单,但在我使我的代码更冗长之前,我希望这样做有一些明显的好处。
解答
使用EXPLAIN来查看差异,如果有的话。
我认为查询重写器会对此进行优化,但我没有检查此示例的源代码。
编辑:我错了,这根本没有优化。其中 ("users"."deleted_at" IS NULL) 可以使用索引,(NOT ("users"."deleted_at" IS NOT NULL)) 条件导致顺序磁盘扫描。
更多推荐
所有评论(0)