【问题标题】:Optimize query with null and false checks in WHERE clause在 WHERE 子句中使用 null 和 false 检查优化查询
【发布时间】:2022-10-24 12:17:12
【问题描述】:

我可以使以下查询更短和/或优化吗?

WITH myvars (t_state, t_hv_involved, num_vehicle_hv )
AS (VALUES ('TAS', null, null))

SELECT * FROM safety.crash_summary_view c, myvars 
WHERE jurisdiction = t_state
AND ((t_hv_involved::boolean = TRUE AND c.num_vehicle_hv > 0)
   OR t_hv_involved is null
   OR t_hv_involved::boolean = FALSE)

如果 t_hv_involvedtrue 那么它应该过滤 num_vehicle_hv > 0
如果t_hv_involvedfalsenull,则不要过滤。

【问题讨论】:

  • 您可以通过省略 = TRUE 并将 t_hv_involved::boolean = FALSE 更改为 NOT t_hv_involved::boolean 来缩短它,但我认为这不是您想要的。

标签: sql postgresql types query-optimization boolean-logic


【解决方案1】:
...
AND   (t_hv_involved IS NOT TRUE OR c.num_vehicle_hv > 0)

假设 t_hv_involvedboolean 的类型,你不需要转换。

The manual:

boolean IS NOT TRUEboolean

测试布尔表达式是否产生 false 或 unknown。
true IS NOT TRUEf
NULL::boolean IS NOT TRUEt(而不是NULL

完整的测试用例可以是:

SELECT *  -- you really need all columns?
FROM   safety.crash_summary_view c
CROSS  JOIN (
   VALUES
     ('TAS', null::bool, null::numeric)
   ) v (t_state, t_hv_involved, num_vehicle_hv)
WHERE  c.jurisdiction = v.t_state
AND   (v.t_hv_involved IS NOT TRUE OR c.num_vehicle_hv > 0);

请注意VALUES 表达式第一行中的显式类型声明。我没有输入'TAS',因为无论如何默认输入text。您可能也想明确并强制转换它。
其他行可以是无类型文字 - 但不能引用 boolean 值。
看:

当然,当您将 null 传递给 num_vehicle_hv 时,c.num_vehicle_hv > 0null,并且测试不会返回包含 v.t_hv_involved IS TRUE 的行。

【讨论】:

  • 也许你应该推荐一个条件索引。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-29
  • 1970-01-01
  • 1970-01-01
  • 2021-02-17
  • 1970-01-01
相关资源
最近更新 更多