【问题标题】:Executing query with wrong NULL operator in where clause在 where 子句中使用错误的 NULL 运算符执行查询
【发布时间】:2014-02-28 14:37:12
【问题描述】:

我想知道当我运行 SQL 时到底发生了什么:

UPDATE pgbench_accounts
SET filler = 'test'
WHERE aid = NULL;

在这种情况下 PostgreSQL 会进行 seq 扫描吗?解释分析因 PostgreSQL 版本而异。 在 9.3 上看起来像:

"Update on pgbench_accounts  (cost=0.00..6266.00 rows=1 width=26) (actual time=0.002..0.002 rows=0 loops=1)"
"  ->  Result  (cost=0.00..6266.00 rows=1 width=26) (actual time=0.000..0.000 rows=0 loops=1)"
"        One-Time Filter: NULL::boolean"
"        ->  Seq Scan on pgbench_accounts  (cost=0.00..6266.00 rows=1 width=26) (never executed)"

但是在以前的版本中缺少“(从不执行)”,所以 PostgreSQL 是否足够聪明,如果操作员错了就不会执行扫描?

【问题讨论】:

  • 算子不是“错”的。发生的情况是,将任何内容与 null 进行比较都会评估为 null,因此不会返回任何行。计划者可以解决这个问题。我猜即使在旧版本中也是如此。
  • @Borys 你想做什么?
  • 创建一个非常大的表,并检查此类查询的总执行时间。如果对数百万行“执行”一次 seq 扫描仍然只需要 0.02 毫秒,那么很可能它并没有真正执行
  • @Borys,你在说什么“其他版本”?我已经将它测试回 8.4,结果是一样的,Seq Scan 由于“一次性过滤器”而“从未执行”。
  • @Borys 获得明确答案的最佳选择是研究相关的规划器代码。不过,这并不容易阅读。

标签: postgresql null where-clause


【解决方案1】:

如果您希望它在参数为空时更新所有行

update pgbench_accounts
set filler = 'test'
where aid = :parameter or :parameter is null;

如果您想要将 null 视为一个公共值

update pgbench_accounts
set filler = 'test'
where aid is not distinct from :parameter;

【讨论】:

  • 这不是我要问的。我需要知道是否会执行 seq 扫描。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多