PostgreSQL 内置索引与手动创建索引 : Performance aspect

标签 postgresql

我正在尝试为我们的应用程序 PostgreSQL 数据库设计最佳索引配置,发现手动为 PK 列创建索引会严重提高估计性能。最初的想法来自here, the first comment .

谁能解释一下:

  1. 为什么 PG 使用手动创建的索引而不是现有的内置索引?
  2. 内置索引是否以某种方式优化以强制执行唯一性,而不是用于选择?
  3. 为什么没有约束时事情看起来更快?

    create table transaction_backup as select * from transaction; 
    analyze select * from transaction_backup where id='8946f500-155c-30a1-a7d0-fb56cdfd114b';
    
    alter table transaction_backup add constraint pk_transaction_backup primary key (id);
    explain analyze select * from transaction_backup where id='8946f500-155c-30a1-a7d0-fb56cdfd114b';
    
    alter table transaction_backup drop constraint pk_transaction_backup;
    create index i_transaction_backup__id on transaction_backup(id);
    explain analyze select * from transaction_backup where id='8946f500-155c-30a1-a7d0-fb56cdfd114b';
    
    drop index i_transaction_backup__id;
    create unique index i_transaction_backup__id on transaction_backup(id);
    explain analyze select * from transaction_backup where id='8946f500-155c-30a1-a7d0-fb56cdfd114b';
    
    alter table transaction_backup add constraint pk_transaction_backup primary key (id);
    explain analyze select * from transaction_backup where id='8946f500-155c-30a1-a7d0-fb56cdfd114b';
    

没有索引

 "Seq Scan on transaction_backup  (cost=0.00..10169.70 rows=1 width=911) (actual time=30.323..68.530 rows=1 loops=1)"
 "  Filter: (id = '8946f500-155c-30a1-a7d0-fb56cdfd114b'::uuid)"
 "  Rows Removed by Filter: 224135"
 **"Planning time: 1.213 ms"
 "Execution time: 68.591 ms"**

PK指标

"Index Scan using pk_transaction_backup on transaction_backup  (cost=0.42..8.44 rows=1 width=911) (actual time=0.127..0.129 rows=1 loops=1)"
"  Index Cond: (id = '8946f500-155c-30a1-a7d0-fb56cdfd114b'::uuid)"
**"Planning time: 1.876 ms"
"Execution time: 0.188 ms"**

仅手动非唯一索引

"Index Scan using i_transaction_backup__id on transaction_backup  (cost=0.42..8.44 rows=1 width=911) (actual time=0.026..0.028 rows=1 loops=1)"
"  Index Cond: (id = '8946f500-155c-30a1-a7d0-fb56cdfd114b'::uuid)"
**"Planning time: 0.214 ms"
"Execution time: 0.096 ms"**

仅手动唯一索引

"Index Scan using i_transaction_backup__id on transaction_backup  (cost=0.42..8.44 rows=1 width=911) (actual time=0.009..0.009 rows=1 loops=1)"
"  Index Cond: (id = '8946f500-155c-30a1-a7d0-fb56cdfd114b'::uuid)"
**"Planning time: 0.340 ms"
"Execution time: 0.054 ms"**

PK 索引 + 手动唯一索引

"Index Scan using i_transaction_backup__id on transaction_backup  (cost=0.42..8.44 rows=1 width=911) (actual time=0.121..0.123 rows=1 loops=1)"
"  Index Cond: (id = '8946f500-155c-30a1-a7d0-fb56cdfd114b'::uuid)"
**"Planning time: 2.001 ms"
"Execution time: 0.187 ms"**

最佳答案

您可能会看到系统中抖动的正常影响。

我建议您采用合理大小的数据集,然后运行几(十/万)千次测试以查看是否存在任何显着差异。

测试做得很好,但我认为您需要一组更具统计意义的数据。

(顺便说一句,请参阅此处 https://aws.amazon.com/blogs/aws/amazon-aurora-update-postgresql-compatibility/ 上的抖动图表以获得有趣的信息)。

关于PostgreSQL 内置索引与手动创建索引 : Performance aspect,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41591714/

相关文章:

sql - 如何在 PostgreSQL 中有效地设置减法连接表?

macos - 使用 boot2docker 将 heroku postgres 数据库转储导入到 docker 数据库容器中

database - 无法恢复或备份 Odoo 数据库

database - 强制 postgres 转储使用复制而不是插入

sql - 一个表怎么会违反它自己的主键索引呢?

使用带子选择的更新对 PostgreSQL 记录重新排序

ruby-on-rails - rails SQL 查询报告使用 postgres 失败但从 psql 命令行工具成功

postgresql - 在我的 mac 上进行 postgresql 本地开发时遇到问题

postgresql - Inno Setup - 等待 Postgres 数据库启动

sql - 在 PostgreSQL 中直到当前日期的每月工作日