您如何有效地确定 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从表限制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 表是不是有行的主要内容,如果未能解决你的问题,请参考以下文章