我正在尝试帮助一位在 PostgreSQL 查询方面遇到问题的同事。
我们将它缩小到一个表的连接,这使得查询变得非常缓慢,并且经过调查,我们发现即使是对“数据”表的简单 select * 请求也需要长达 2 分钟才能返回结果。
该表包含 420,000 条记录和 13 列,其中没有一个是 BLOB 或任何大量内容(它们都是文本)。
运行 EXPLAIN ANALYZE VERBOSE 大大低估了返回结果所需的时间
即对于 SELECT * FROM DATA
"Seq Scan on data (cost=0.00..18284.35 rows=389735 width=27)
(actual time=0.135..594.929 rows=426934 loops=1)"
" Output: id,..."
"Total runtime: 1069.643 ms"
Run Code Online (Sandbox Code Playgroud)
而在没有 EXPLAIN 的情况下运行查询会给出
Total query runtime: 86598 ms.
426934 rows retrieved.
Run Code Online (Sandbox Code Playgroud)
如果我在提问时违反了任何惯例,我很抱歉,但我根本不了解 Postgres,所以如果有人能建议我们应该寻找什么样的潜在问题来帮助解决这个问题,我将不胜感激已收到。
编辑:根据要求,表定义
CREATE TABLE data
(
id text NOT NULL,
methodid text NOT NULL,
replicateid text,
t_id text NOT NULL,
t_name text NOT NULL,
a_id text NOT NULL,
originalname text,
qualifier text,
frequency text,
frequencyunits text NOT NULL,
determiner text,
sensitive text,
versionkey text,
CONSTRAINT data_pkey PRIMARY KEY (id),
CONSTRAINT sample FOREIGN KEY (sid)
REFERENCES sample (sid) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
WITH (
OIDS=FALSE
);
CREATE INDEX eventid_idx
ON data
USING btree
(id);
Run Code Online (Sandbox Code Playgroud)
运行 EXPLAIN ANALYZE VERBOSE 大大低估了返回结果所需的时间
有一种误解在这里,因为EXPLAIN ANALYZE
没有估计,它运行实际的查询和报告每个步骤所采取的实际时间,而不是EXPLAIN
没有ANALYZE
,只是没有报告运行查询的估计。
考虑您的 EXPLAIN ANALYZE 输出中的这一行:
(实际时间=0.135..594.929行=426934循环=1)
这 595 毫秒不是估计值,而是实际时间。此外,当 postgres 显示估算值时,它们以“成本”为单位表示,而不是以时间单位表示。
完成后,EXPLAIN ANALYZE 将分析的结果发送回客户端,并丢弃实际结果的行。这与真正的 SELECT 不同,后者必须将行发送回客户端。
出于这个原因,在您的情况下,两种操作之间的巨大差异可能/应该由接收结果的缓慢引起,要么是因为网络慢,要么是因为客户端很慢,或两者兼而有之。如果结果集太大而无法容纳在可用的 RAM 中,则客户端可能会疯狂地交换。在这 2 分钟内,我会查看服务器和客户端上的vmstat 1
和iftop
输出(甚至strace
),以检查正在做什么。
归档时间: |
|
查看次数: |
5560 次 |
最近记录: |