您如何有效地确定 Postgres 表是不是有行

Posted

技术标签:

【中文标题】您如何有效地确定 Postgres 表是不是有行【英文标题】:How do you efficiently determine if a Postgres table has rows您如何有效地确定 Postgres 表是否有行 【发布时间】:2010-09-19 01:07:56 【问题描述】:

我做了这个测试,结果似乎计数函数是线性缩放的。我有另一个函数非常依赖效率来知道是否有任何数据,所以我想知道如何用另一个更有效的(可能是常数?)查询或数据结构替换这个 select count(*)。

psql -d testdb -U postgres -f truncate_and_insert_1000_rows.sql > NUL

psql -d testdb -U postgres -f count_data.sql

----------------------------------------------- ----------------------------------

聚合(成本=36.75..36.76 行=1 宽度=0)(实际时间=0.762..0.763 行=1 循环=1) -> Seq Scan on datos (cost=0.00..31.40 rows=2140 width=0) (实际时间=0.02 8..0.468 行=1000 次循环=1) 总运行时间:0.846 毫秒 (3 条)

psql -d testdb -U postgres -f truncate_and_insert_10000_rows.sql > NUL

psql -d testdb -U postgres -f count_data.sql

----------------------------------------------- ----------------------------------

聚合(成本=197.84..197.85 行=1 宽度=0)(实际时间=6.191..6.191 行= 1 个循环=1) -> Seq Scan on datos (cost=0.00..173.07 rows=9907 width=0) (实际时间=0.0 09..3.407 行=10000 循环=1) 总运行时间:6.271 毫秒 (3 条)

psql -d testdb -U postgres -f truncate_and_insert_100000_rows.sql > NUL

psql -d testdb -U postgres -f count_data.sql

----------------------------------------------- ----------------------------------

聚合(成本=2051.60..2051.61 行=1 宽度=0)(实际时间=74.075..74.076 r ows=1 循环=1) -> Seq Scan on datos (cost=0.00..1788.48 rows=105248 width=0) (实际时间= 0.032..46.024 行=100000 循环=1) 总运行时间:74.164 毫秒 (3 条)

psql -d prueba -U postgres -f truncate_and_insert_1000000_rows.sql > NUL

psql -d testdb -U postgres -f count_data.sql

----------------------------------------------- ----------------------------------

聚合(成本=19720.00..19720.01 行=1 宽度=0)(实际时间=637.486..637.4 87 行=1 循环=1) -> Seq Scan on datos (cost=0.00..17246.60 rows=989360 width=0) (实际时间 =0.028..358.831 行=1000000 循环=1) 总运行时间:637.582 毫秒 (3 条)

数据的定义是

CREATE TABLE data
(
  id INTEGER NOT NULL,
  text VARCHAR(100),
  CONSTRAINT pk3 PRIMARY KEY (id)
);

【问题讨论】:

我也试过限制结果集:EXPLAIN ANALYZE select count(*) from data LIMIT 1;但响应时间非常相似...... 那是因为你需要测试 SELECT * FROM LIMIT 1.
【参考方案1】:

从表限制1中选择true;

【讨论】:

【参考方案2】:
select exists(select * from your_table_here) as has_row

【讨论】:

Exists 如果内部查询返回任何行,则返回 true。它实际上并不检查行的内容,因此* 并不意味着检索字段。 唐尼:确实。其实即使你把1/0放在SELECT FROM your_table_here里面,也不会被零除错误【参考方案3】:

试试这个:

SELECT t.primary_key IS NOT NULL FROM table t LIMIT 1;

如果有记录,则为 TRUE,如果没有记录,则为 NULL。

【讨论】:

-1 不是最佳解决方案,因为您正在检查表中的列,如果您检查的列没有 NOT NULL 约束,则该列可能不准确。改为SELECT 1 FROM table LIMIT 1 会好得多。【参考方案4】:

如果您只关心 1 行或没有行。将您的查询限制在第一行 - 为什么要计算所有行只是为了找出是否有 1 或更多,或者为零...

使用 ROWNUM = 1 或 TOP 1 或任何 postgres 给你的等价物。

【讨论】:

谢谢,我讨厌人们为其他平台提供解决方案,但我知道这个概念肯定必须非常相似。【参考方案5】:

如何计算不为 NULL 的主键字段,将查询限制为 1 个响应?

既然主键必须存在,如果有,你有数据,是吗?

【讨论】:

【参考方案6】:

您可能会发现this 很有用。

【讨论】:

该链接已损坏。现在内容位于wiki.postgresql.org/wiki/Slow_Counting

以上是关于您如何有效地确定 Postgres 表是不是有行的主要内容,如果未能解决你的问题,请参考以下文章

如何确定数组中的值是不是存在于 Postgres 表中

如何有效地将 Postgres 数据从 Query 传输到 S3

在 postgres 上将表导出到 csv

如何有效地检查表是不是为空?

如何确定 postgres 视图是不是可更新

如何使用 SQL 有效地确定行之间的更改