如何高效地编写SQL条件?

ste*_*lla 3 sql postgresql

我有以下非常大的(~10e8记录)表(table):

+--------------------------------+
|      id      order       value |
+--------------------------------+
|      PK       int         int  |
|       1        1           1   |
|       2        2           5   |
|       3        2               |
|       4        2           0   |
+--------------------------------+

如您所见,value列只能包含非负整数或null.现在,我需要编写一个返回没有a的订单的查询value > 0(即order = 2不保存条件,因为有记录value = 5).

反向查询很简单:

SELECT order
FROM table
WHERE value > 0
Run Code Online (Sandbox Code Playgroud)

查询的性能对我来说是令人满意的.

但我们不能写

SELECT order
FROM table
WHERE value = 0
Run Code Online (Sandbox Code Playgroud)

因为有可能有一个具有相同订单的记录,但有value > 0.我能找到写这个查询的唯一方法是:

SELECT order
FROM table
GROUP BY order
HAVING SUM(COALESCE(value, 0)) = 0
Run Code Online (Sandbox Code Playgroud)

但是由于计算了大量数据的总和,查询非常慢.

有没有办法更有效地编写查询?

Gor*_*off 7

它可能更快使用exists:

select o.*
from orders o
where not exists (select 1
                  from table t
                  where t.order = o.order and t.value > 0
                 );
Run Code Online (Sandbox Code Playgroud)

这假设您有一个只包含订单的表(orders在查询中调用).此外,它最适合索引table(order, value).

我也想知道以下查询是否具有索引的可接受性能 table(order, value desc)

select t.*
from (select distinct on (order) t.*
      from table t
      order by order, value desc
     ) t
where value = 0;
Run Code Online (Sandbox Code Playgroud)

distinct on应使用索引排序,只是把遇到的第一行.然后外部where将过滤这些,但两次扫描可能会非常快.