当我从下表中选择(包含6个百万行)时,需要5分钟才能完成以下声明:
SELECT * FROM public.matchmsg order by tradeid desc
我做错了什么?
表格定义
CREATE TABLE public.matchmsg
(
id bigint NOT NULL DEFAULT nextval('matchmsg_id_seq'::regclass),
tradeid bigint NOT NULL,
matchdate timestamp with time zone,
price double precision NOT NULL,
size double precision NOT NULL,
issell boolean NOT NULL,
CONSTRAINT matchmsg_pkey PRIMARY KEY (id)
)
WITH (
OIDS=FALSE,
autovacuum_enabled=true
);
ALTER TABLE public.matchmsg
OWNER TO mb;
CREATE UNIQUE INDEX tradeid_idx
ON public.matchmsg
USING btree
(tradeid);
更新1:
EXPLAIN ANALYSE SELECT * FROM public.matchmsg;
"Seq Scan on matchmsg (cost=0.00..117720.03 rows=6000103 width=41) (actual time=0.041..837.495 rows=6000102 loops=1)"
"Planning time: 1.769 ms"
"Execution time: 914.932 ms"
查询是否应该在117秒内执行?
更新2:
EXPLAIN ANALYSE SELECT * FROM public.matchmsg order by tradeid
"Index Scan using tradeid_idx on matchmsg (cost=0.43..278622.57 rows=6177667 width=41) (actual time=0.172..1465.935 rows=6177670 loops=1)"
"Planning time: 0.246 ms"
"Execution time: 1553.377 ms"
更新3:
要获得正确和正确的答案,你还必须提出正确的问题......也许我没有......我意识到只选择6M行并没有多大意义......但事实上我做了 - 我不明白为什么我的电脑如此缓慢地给我一个正确的反应(我仍然不 - 无论数据库,用户界面还是什么 - 我认为5分钟太慢 - 我使用Postgres自己的原生工具:PG企业M.或PG pgAdminIII - 它们完全相同)。什么工具更快/更好,你们用什么用Postgresql?
我现在也意识到索引没有任何帮助 - 当我选择所有行和所有列时。
我试图运行CLUSTER语句 - 但它没有改变任何东西 - 据我所知......?
与6M行有什么关系?好吧 - 我会随着时间的推移用算法/模式做很多不同的分析...所以取决于我将需要的数学/表达式以及计算ect的难度/难度......我想我有2个选项从这里:
要么通过DB中的SQL执行所有需要的数学运算,要么将1000行(只有某些列/ s)加载到我的nodejs代码中,对给定的加载数据进行数学运算...遍历整个数据库。
对于您的信息,以下声明的执行方式如下:
select SUM(price) from matchmsg --> about 1 sec!
SELECT tradeid FROM matchmsg order by tradeid asc limit 1000 offset 5000000 --> about 1 sec!
我也尝试过执行
"SELECT * FROM matchmsg"
在nodeJS内部 - 但是在30秒左右之后崩溃 - 出现错误desc:
"FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory".
但更有趣的是:
"SELECT tradeid FROM matchmsg" --> 7 sec!
我甚至可以选择结果集[5000000]并在我的nodeJS应用程序内的7秒内获得该位置的交易...
所有这些事实都将在一天结束时全部结束 - 我只需要了解真正的数学,以了解要走哪条路......
答案 0 :(得分:0)
这是正常行为。在这种情况下,主要问题通常是用户必须等待很多事实。在整个数据加载过程中,您可能会考虑重复发送数据块,以显示数据的一部分。此外,您可能会考虑使用分页,这或多或少是一个标准,但这样的任务的等待时间是很正常的。
答案 1 :(得分:0)
您应该使用EXPLAIN ANALYZE
条款向SELECT
显示ORDER BY
。你可能会看到的是索引没有被使用。由于排序会占用有序结果集查询中的大部分时间,因此未排序的SELECT
不会提供任何信息来解决您的问题。 (关于117秒的执行时间:我认为你指的是cost=0.00..117720.03
,这是任意单位成本的相对衡量标准,具体取决于postgresql.conf
中的设置;它与...无关时间或任何其他物理财产。)
默认情况下,索引的结束顺序为ASC
,您的查询需要DESC
结束顺序的行。因此,要么将索引更改为使用降序,要么为此特定查询创建其他索引:
CREATE UNIQUE INDEX tradeid_idx_desc
ON public.matchmsg
USING btree
(tradeid DESC);
但即使这样,时间也不会减少,因为你要求表中的所有行,所以不会使用索引,但见下文。
另一种方法是使用上面的索引CLUSTER
表。这将导致表的一次性物理排序。如果不经常更新行,那么这将显着提高您感兴趣的查询的速度。在新行的一定数量的插入之后,排序速度将降低,因为PG不维护群集,因此您应该定期{ {1}}保持表现的表格。
看到不同海报之间的讨论,在没有OP的情况下,我重新创建了OP表并运行了各种感兴趣的查询。
表格完全相同。 CLUSTER
声明:
INSERT
由于INSERT INTO matchmsg (tradeid, matchdate, price, size, issell)
SELECT (random() * 4100000000000000000)::bigint, now(), 3.23, 12.2, true
FROM generate_series(1, 6000103);
的随机值分配,ASC
和DESC
的索引都不是UNIQUE
。
tradeid
简单patrick@puny:~$ psql -d test
psql (9.5.0, server 9.4.5)
Type "help" for help.
test=# EXPLAIN ANALYZE SELECT * FROM matchmsg;
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------
Seq Scan on matchmsg (cost=0.00..116076.90 rows=6000090 width=37) (actual time=0.017..637.483 rows=6000103 loops=1)
Planning time: 0.601 ms
Execution time: 854.207 ms
(3 rows)
test=# EXPLAIN ANALYZE SELECT * FROM matchmsg ORDER BY tradeid DESC;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------------
Index Scan using tradeid_idx_desc on matchmsg (cost=0.43..380121.64 rows=6000090 width=37) (actual time=0.056..15836.728 rows=6000103 loops=1)
Planning time: 0.234 ms
Execution time: 16160.661 ms
(3 rows)
test=# CLUSTER matchmsg USING tradeid_idx_desc;
CLUSTER
test=# EXPLAIN ANALYZE SELECT * FROM matchmsg ORDER BY tradeid DESC;
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------------
Index Scan using tradeid_idx_desc on matchmsg (cost=0.43..380121.84 rows=6000103 width=37) (actual time=0.029..1158.271 rows=6000103 loops=1)
Planning time: 0.289 ms
Execution time: 1377.929 ms
(3 rows)
提供与OP相同的性能指标(这是一个简单的网络,PG在一台单独的机器上运行)。由于排序,SELECT *
查询确实使用 ORDER BY
索引,但需要16秒。在降序索引上DESC
之后,查询时间减少了12倍(给定或接受)。