PostgreSQL中有一种更快的方法可以基本上在几行中执行if吗?
说我有一张桌子
ticket | row | archived
1 | 1 | true
1 | 2 | true
1 | 3 | true
2 | 1 | false
2 | 2 | true
有什么方法可以在ticket =的列下面做一个if语句? 因此,如果<= p>,则ticket = 1将成立
true && true && true = true
并且ticket = 2将为false,因为
false && true = false
或者我应该坚持使用
SELECT ( (SELECT COUNT(*) FROM table WHERE ticket = 1)
= (SELECT COUNT(*) FROM table WHERE ticket = 1 AND archived = true) )
答案 0 :(得分:15)
bool_and()
简单,简洁,清晰。
SELECT bool_and(archived)
FROM tbl
WHERE ticket = 1;
我引用手册here:
true if all input values are true, otherwise false
EXISTS
- 与@Mike provided 更快。但是,您必须另外检查是否存在ticket = 1
的任何行,或者您对不存在的票证的结果不正确:
SELECT EXISTS (SELECT 1 FROM tbl WHERE ticket=1)
AND NOT
EXISTS (SELECT 1 FROM tbl WHERE ticket=1 AND archived = FALSE);
两种形式都可以并且将使用如下索引:
CREATE index tbl_ticket_idx ON tbl (ticket);
..这使得两者都快,但EXISTS
查询更快,因为一旦找到第一个匹配的行,此表单就可以停止扫描。两个查询之间几乎没有任何区别,每个票证只有几行,但每张票证的许多行存在实质性差异。
要在第9.2页中使用仅索引扫描,您需要multi-column index的格式:
CREATE index tbl_ticket_archived_idx ON tbl (ticket, archived);
这个更好 任何情况下大多数情况和任何版本的PostgreSQL。由于data alignment,在索引中向boolean
添加integer
不会使索引增长。几乎没有任何成本增加了好处。
但是,索引列会阻止HOT(Heap Only Tuple)更新。假设UPDATE
仅更改列archived
。如果该列未被任何索引使用(以任何方式),则可以对该行进行HOT更新。否则,不能采用这种快捷方式。我写了more on HOT updates in this related answer。
因此,一如既往,这完全取决于您的确切工作量。
答案 1 :(得分:5)
如下:
select not exists (select 1 from table where ticket=1 and not archived)
我认为这可能比计算count
may or may not use an index更有利,而且您需要知道的是,任何 FALSE
行是否存在那张票。我认为只在ticket
创建一个部分索引可能会非常快。
答案 2 :(得分:1)
select not false = any (
select archived
from foo
where ticket = 1
)