sql - "x IS NULL"和 "NOT (x IS NOT NULL)"有什么区别?

标签 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),但对于other search_terms 它可以是各种子句,包括复合子句和子选择。在最后添加.not,arel 将始终生成第二种形式的SQL。我可以通过对我的NULL 检查进行特殊封装并手动生成.eq.not_eq 作为情况可能是这样,但在我使我的代码更冗长之前,我希望这样做有一些明显的好处。

最佳答案

使用EXPLAIN看看有什么区别,如果有的话。

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

编辑:我错了,这根本没有优化。在 ("users"."deleted_at"IS NULL) 可以使用索引的地方,(NOT ("users"."deleted_at"IS NOT NULL)) 条件导致顺序磁盘扫描。

关于sql - "x IS NULL"和 "NOT (x IS NOT NULL)"有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8618427/

相关文章:

sql - 滚动每日不同计数

python - MYSQLdb/Python 值错误但仍得到所需结果

ruby-on-rails - rake 太阳黑子 :solr:start throwing an error

c++ - 从 C++ (gcc) 连接到 PostgreSQL

python - 与 SQLAlchemy-Continuum 的多对多关系插入具有重复 transaction_id 的记录

postgresql - Sequelize 数据库错误: column does not exist (Postgresql)

sql - 我想在我现有的配置单元表中添加一个额外的列,以便我可以获得当天的当前时间戳

mysql - 使用限制SQL后检查查询数量

sql - Rails find_by_sql 依赖于数据库类型

ruby-on-rails - 如何在此 ruby​​ 表单中发出错误通知?