我正在尝试为我们的应用程序 PostgreSQL 数据库设计最佳索引配置,发现手动为 PK 列创建索引会严重提高估计性能。最初的想法来自here, the first comment .
谁能解释一下:
- 为什么 PG 使用手动创建的索引而不是现有的内置索引?
- 内置索引是否以某种方式优化以强制执行唯一性,而不是用于选择?
为什么没有约束时事情看起来更快?
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/