【发布时间】:2021-07-25 20:15:20
【问题描述】:
我有类似下表的内容
CREATE TABLE mytable
(
id serial NOT NULL
search_col int4 NULL,
a1 varchar NULL,
a2 varchar NULL,
...
a50 varchar NULL,
CONSTRAINT mytable_pkey PRIMARY KEY (id)
);
CREATE INDEX search_col_idx ON mytable USING btree (search_col);
这个表大约有 500 万行,执行类似的搜索操作大约需要 15 秒
select *
from mytable
where search_col = 83310
提高性能对我来说至关重要,但即使在search_col 之后对表进行聚类也没有带来很大的好处。
但是,我尝试了以下方法:
create table test as (select id, search_col, a1 from mytable);
在此表上进行搜索,其行数与原始表相同,大约需要 0.2 秒。为什么会这样,我该如何使用它来满足我的需要?
Index Scan using search_col_idx on mytable (cost=0.43..2713.83 rows=10994 width=32802) (actual time=0.021..13.015 rows=12018 loops=1)
Seq Scan on test (cost=0.00..95729.46 rows=12347 width=19) (actual time=0.246..519.501 rows=12018 loops=1)
DBeaver 执行计划的结果
|Knotentyp|Entität|Kosten|Reihen|Zeit|Bedingung|
|Index Scan|mytable|0.43 - 3712.86|12018|13.141|(search_col = 83310)|
来自 psql 的执行计划:
Index Scan using mytable_search_col_idx on mytable (cost=0.43..3712.86 rows=15053 width=32032) (actual time=0.015..13.889 rows=12018 loops=1)
Index Cond: (search_col = 83310)
Planning time: 0.640 ms
Execution time: 23.910 ms
(4 rows)
【问题讨论】:
-
如果可能的话,您能否为您的两个单独的查询添加解释和分析,它将提供更多关于您的 SQL 正在做什么的上下文。
-
请edit您的问题并添加使用
explain (analyze, buffers, format text)生成的execution plan(不是只是一个“简单”解释)为formatted text,并确保保留计划的缩进。将结果复制为文本,然后粘贴文本并将```放在计划前一行和计划后一行。 -
我就是这么做的
-
这不是一个完整的执行计划。
-
看起来您在该表的每一行中有五十个文本列。您的
SELECT *查询会全部获取它们,将它们序列化,然后通过网络将它们从您的 pg 服务器推送到您的客户端程序。你总是使用结果中的所有列吗?如果没有,也许您应该尝试枚举您需要的列。SELECT a3, a11, a25例如。五十列是很多。如果它们中的许多在任何给定行中为空,它甚至可能会被非规范化。如果性能至关重要,请考虑对其进行重组。
标签: sql postgresql performance indexing query-optimization