如何高效地编写SQL条件?

时间:2015-07-25 12:33:21

标签: sql postgresql

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

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

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

反向查询 很简单:

SELECT order
FROM table
WHERE value > 0

查询的效果对我来说是令人满意的。

但我们不能写完

SELECT order
FROM table
WHERE value = 0

因为可能有一个具有相同顺序的记录,但是value > 0。我能找到编写该查询的唯一方法是:

SELECT order
FROM table
GROUP BY order
HAVING SUM(COALESCE(value, 0)) = 0

但由于计算了大量数据的总和,查询速度很慢。

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

1 个答案:

答案 0 :(得分:7)

使用exists

可能会更快
select o.*
from orders o
where not exists (select 1
                  from table t
                  where t.order = o.order and t.value > 0
                 );

这假设您有一个只包含订单的表(在查询中称为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;

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