我有一个 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
我试图让 PostgreSQL 积极地自动清空我的数据库。我目前已按如下方式配置自动真空吸尘器:
我注意到自动真空仅在数据库未加载时才会启动,因此我遇到死元组比活元组多得多的情况。有关示例,请参阅随附的屏幕截图。其中一张表有 23 个活动元组,但有 16845 个死元组等待真空。这太疯狂了!
当测试运行完成并且数据库服务器空闲时,自动真空开始,这不是我想要的,因为我希望自动真空在死元组数量超过 20% 活元组 + 50 时启动,因为数据库已经配置。服务器空闲时的自动真空对我来说是无用的,因为生产服务器预计会在持续时间内达到 1000 次更新/秒,这就是为什么即使服务器负载不足我也需要自动真空运行。
有什么我想念的吗?如何在服务器负载较重时强制运行自动吸尘器?
更新
这可能是一个锁定问题吗?有问题的表是通过插入后触发器填充的汇总表。这些表以 SHARE ROW EXCLUSIVE 模式锁定,以防止并发写入同一行。
我有一个名为auto_review
where column type is的数据库列boolean
。该字段有一个索引,使用 ActiveRecord ORM 创建。
CREATE INDEX index_table_on_auto_renew ON table USING btree (auto_renew);
Run Code Online (Sandbox Code Playgroud)
当我查询布尔值的字段时,PG 按预期使用索引。
EXPLAIN for: SELECT "table".* FROM "table" WHERE "table"."auto_renew" = 'f'
QUERY PLAN
----------------------------------------------------------------------------------------------
Bitmap Heap Scan on table (cost=51.65..826.50 rows=28039 width=186)
Filter: (NOT auto_renew)
-> Bitmap Index Scan on index_domains_on_auto_renew (cost=0.00..44.64 rows=2185 width=0)
Index Cond: (auto_renew = false)
(4 rows)
Run Code Online (Sandbox Code Playgroud)
当值为 时NULL
,使用顺序扫描。
EXPLAIN for: SELECT "table".* FROM "table" WHERE "table"."auto_renew" IS NULL
QUERY PLAN
----------------------------------------------------------------
Seq Scan …
Run Code Online (Sandbox Code Playgroud) 我们有一个整数列,目前仅包含 0 或 1 个值。此列现在已被开发人员用于在某些情况下存储唯一的 32 位标识符,我们需要能够有效地提取包含这些标识符中的任何一个的行。
鉴于该值在 99% 的情况下是 0 或 1(我还没有数字),如何最好地索引以查询少数情况?我认为共同价值的数量将成为一个问题是否正确?
Column | Type | Modifiers
----------------------------+---------+--------------------
event_value | integer | not null
Run Code Online (Sandbox Code Playgroud)
此列当前没有索引。而且我不认为需要定期只选择 0 或 1 值。
该表大小合理,目前有 3000 万行并且增长很快。
我很欣赏这不是该专栏的最佳用途,但在短期内不会改变。
在 PostgreSQL 9.3 中,我试图在一个很少使用的(占总记录的 0.00001%)布尔列上创建一个有效的索引。为此,我在 SO 上发现了这篇文章: https //stackoverflow.com/a/12026593/808921
我正在尝试利用 Erwin Brandstetter 推荐的 PostgreSQL 的“部分索引”功能。我已经有一个包含几百万条记录的表,我想将索引添加到该表中,如下所示:
CREATE INDEX schema_defs_deprovision ON schema_defs (deprovision)
WHERE deprovision = 0;
Run Code Online (Sandbox Code Playgroud)
(绝大多数记录都会有 deprovision = 1
)
问题是,当我尝试将此索引与最简单的查询一起使用时,PostgreSQL 就好像它不存在一样:
explain select * from schema_defs where deprovision = 0;
Seq Scan on schema_defs (cost=0.00..1.05 rows=1 width=278)
Filter: (deprovision = 0)
Run Code Online (Sandbox Code Playgroud)
真正奇怪的是,我发现如果这个索引是在表中有数据之前创建的,那么它确实可以正常工作。不相信我?以下是一些证明这一点的 SQL Fiddle 条目:
插入后创建的部分索引(索引不起作用)
插入前创建的部分索引(索引正常工作)
在这两个中,只需展开“查看执行计划”链接即可查看我在说什么。
所以,我的问题是 - 我必须做什么才能让 PostgreSQL 在创建索引之前开始在其中包含数据的表上使用部分索引?
顺便说一句,我也是 SQL Fiddle 的开发人员,这个问题与我正在为此进行的一项新开发工作有关。
在另一个问题中,我了解到我应该从我的一个表中优化布局以节省空间并获得更好的性能。我这样做了,但最终得到了比以前更大的表,并且性能没有改变。当然我做了一个VACUUM ANALYZE
. 怎么会?
(我看到如果我只索引单列,索引大小不会改变。)
这是我来自的表(我添加了尺寸 + 填充):
Table "public.treenode"
Column | Type | Size | Modifiers
---------------+--------------------------+------+-------------------------------
id | bigint | 8 | not null default nextval( ...
user_id | integer | 4+4 | not null
creation_time | timestamp with time zone | 8 | not null default now()
edition_time | timestamp with time zone | 8 | not null default now()
project_id | integer | 4 | not null
location | real3d | 36 | …
Run Code Online (Sandbox Code Playgroud) 我的表包含列的索引total_balance
:
\d balances_snapshots
Table "public.balances_snapshots"
Column | Type | Collation | Nullable | Default
---------------+-----------------------------+-----------+----------+------------------------------------------------
user_id | integer | | |
asset_id | text | | |
timestamp | timestamp without time zone | | | now()
total_balance | numeric | | not null |
id | integer | | not null | nextval('balances_snapshots_id_seq'::regclass)
Indexes:
"balances_snapshots_pkey" PRIMARY KEY, btree (id)
"balances_snapshots_asset_id_idx" btree (asset_id)
"balances_snapshots_timestamp_idx" btree ("timestamp")
"balances_snapshots_user_id_idx" btree (user_id)
"balances_total_balance_idx" btree (total_balance)
Foreign-key constraints:
"balances_snapshots_asset_id_fkey" FOREIGN KEY (asset_id) …
Run Code Online (Sandbox Code Playgroud) 在我的PostgreSQL 12.8数据库中,我有一个相对简单的表the_table
,其中有一列value
类型为varchar
:
CREATE TABLE public.the_table (
id uuid DEFAULT gen_random_uuid() NOT NULL,
label character varying,
value character varying,
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL,
);
Run Code Online (Sandbox Code Playgroud)
我想查询具有格式为电子邮件地址的值的所有行。查询看起来像这样:SELECT * FROM the_table WHERE value ~ '^[a-zA-Z0-9.$%&*+/=?^_{|}~-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9]+$'
。
由于该表中有几百万行,我尝试通过添加匹配的表达式索引来加速此查询CREATE INDEX index_the_table_on_email_values ON the_table ((value ~ '^[a-zA-Z0-9.$%&*+/=?^_{|}~-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9]+$'));
不幸的是,查询计划程序不使用索引,而是对表执行完整扫描,这非常慢。
有人可以帮我修复索引或告诉我还有什么其他选择吗?我已经考虑过生成布尔列is_email
。我可以向生成的列添加索引并直接查询它。但这对于原始问题来说似乎是一个奇怪的解决方法,应该可以通过匹配的索引来解决,对吗?
是否可以reltuples
使用附加条件查询给定表的列table.name LIKE 'hello%'
?
目前在我更大的表上,SELECT count(*)
查询需要很长时间,我不需要确切的计数。所以我想知道是否可以WHERE
在 the 中添加子句reltuples
?
postgresql ×9
index ×6
datatypes ×2
disk-space ×2
performance ×2
vacuum ×2
count ×1
regex ×1
size ×1
statistics ×1