我有一个 PostgreSQL 表。select *
很慢,但又select id
好又快。我认为可能是行的大小非常大并且需要一段时间来运输,或者可能是其他一些因素。
我需要所有字段(或几乎所有字段),因此仅选择一个子集不是一个快速解决方案。选择我想要的字段仍然很慢。
这是我的表架构减去名称:
integer | not null default nextval('core_page_id_seq'::regclass)
character varying(255) | not null
character varying(64) | not null
text | default '{}'::text
character varying(255) |
integer | not null default 0
text | default '{}'::text
text |
timestamp with time zone |
integer |
timestamp with time zone |
integer |
Run Code Online (Sandbox Code Playgroud)
文本字段的大小可以是任意大小。但是,在最坏的情况下,不会超过几千字节。
postgresql performance size disk-space postgresql-performance
VACUUM
通常不会将磁盘空间返回给操作系统,除非在某些特殊情况下。
从文档:
VACUUM
删除表和索引中的死行版本并标记可用空间以供将来重用的标准形式。但是,它不会将空间返回给操作系统,除非在表末尾的一个或多个页面完全空闲并且可以轻松获得排他表锁的特殊情况下。相比之下,VACUUM FULL
通过编写一个没有死空间的完整新版本的表文件来主动压缩表。这最大限度地减少了表的大小,但可能需要很长时间。它还需要额外的磁盘空间用于表的新副本,直到操作完成。
问题是:如何实现这个数据库状态one or more pages at the end of a table become entirely free
?这可以通过 完成VACUUM FULL
,但我没有足够的空间来实现它。那么还有没有其他可能呢?
我有一个基于日期字段和数字字段的订单查询 Postgres 中的表,该表有 1000000 条记录
表的数据类型为:
fcv_id = serial
fcv_fecha_comprobante = timestamp without time zone
fcv_numero_comprobante = varchar(60)
Run Code Online (Sandbox Code Playgroud)
查询是:
SELECT fcv_id, fcv_fecha_comprobante FROM factura_venta
ORDER BY fcv_fecha_comprobante, fcv_numero_comprobante
Run Code Online (Sandbox Code Playgroud)
这个查询大约需要 5 秒,但如果我取出“order by”,查询只需要 0.499 秒
我遇到的问题是我需要在尽可能短的时间内运行这个查询,所以我在谷歌上搜索我可以做什么并使用以下查询创建一个复合索引
CREATE INDEX factura_venta_orden ON factura_venta
USING btree (fcv_fecha_comprobante ASC NULLS LAST
, fcv_numero_comprobante ASC NULLS LAST);
ALTER TABLE factura_venta CLUSTER ON factura_venta_orden;
Run Code Online (Sandbox Code Playgroud)
但是查询花费的时间相同甚至更多。
我使用的是 Postgres 9.0.13,这里是 73436 行的 EXPLAIN
Sort (cost=11714.03..11897.62 rows=73436 width=27) (actual time=1260.759..1579.853 rows=73436 loops=1)
Sort Key: fcv_fecha_comprobante, fcv_numero_comprobante
Sort Method: external merge …
Run Code Online (Sandbox Code Playgroud)