gpt4 book ai didi

sql - 完整性检查 : count(*) vs count(pkColumn)

转载 作者:行者123 更新时间:2023-11-29 11:53:52 24 4
gpt4 key购买 nike

今天我的老板告诉我使用 count(pkColumn) 而不是 count(*),说这样会更快。我很确定这不是真的,但我不是 DBA,而是 Java 开发人员,所以我想核实一下。

我运行了一些查询计划:

EXPLAIN SELECT COUNT(*) FROM "Foo";
EXPLAIN SELECT COUNT("FooUID") FROM "Foo";
EXPLAIN SELECT COUNT(1) FROM "Foo";

结果:

Aggregate  (cost=1421.01..1421.02 rows=1 width=0)
-> Seq Scan on "Foo" (cost=0.00..1296.81 rows=49681 width=0)

Aggregate (cost=1421.01..1421.02 rows=1 width=16)
-> Seq Scan on "Foo" (cost=0.00..1296.81 rows=49681 width=16)

Aggregate (cost=1421.01..1421.02 rows=1 width=0)
-> Seq Scan on "Foo" (cost=0.00..1296.81 rows=49681 width=0)

它们看起来是一样的。有人可以确认我对此是正确的吗?我意识到这已经针对其他语言进行了讨论,但据我所知,PostgreSQL 处理 COUNT 的方式不同,而且我找不到与 PostgreSQL 等效的问题。

请注意,"FooUID" 永远不会是 NULL

编辑:使用版本 9.0.4

最佳答案

你的老板被误导了(充其量)。

是的,PostgreSql(至少我用过的那些,高达 8.1)确实对待 count 略有不同,因为它必须转到实际的表来获取一些信息,而不是仅仅使用单独索引(使用 MVCC ,它在表中存储“软”删除信息,因此必须检索每一行以查看它是否已被删除但尚未从索引中删除)。

但无论您使用 * 还是 pk_column 进行计数,它都必须这样做。使用 * 的优点是 DBMS 可以自由选择任何非空列进行计数,这可能会减少索引处理的磁盘 I/O。

如果您的老板担心性能,您可以使用一些可能的“技巧”。

首先,如果您只对行的存在而不是数量感兴趣,您可以使用如下更改代码:

select count(*) into myCount from myTable where myCondition;
if myCount > 0 then
do something
end if;

进入:

if exists ( select * from myTable where myCondition ) then
do something
end if;

其次,您可以使用insertdelete 触发器,它们在单独的表中为添加的行和删除的行维护两个计数器。然后,您可以通过简单地从另一个中减去一个来计算行数。使用两个单独的计数器可以防止插入/删除操作的序列化,但它仍然是一个巨大的困惑,对于大量情况来说可能是不必要的。

您还必须定期缩减计数器(例如,将 1000 次插入 + 200 次删除 修改为 800 次插入和 0 次删除)。

第三,您可以估计行数(基于上次分析操作):

select reltuples from pg_class where relname = 'myTable';

关于sql - 完整性检查 : count(*) vs count(pkColumn),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7410779/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com