PostgreSQL内置索引与手动创建:性能方面

时间:2017-01-11 13:03:33

标签: postgresql

我正在尝试为我们的应用程序PostgreSQL DB设计最佳索引配置,并发现为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';
    
  4. 没有索引

     "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"**
    

1 个答案:

答案 0 :(得分:3)

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

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

测试做得不错,但我认为您需要更具统计意义的数据集。

(顺便提一下这里的抖动图表https://aws.amazon.com/blogs/aws/amazon-aurora-update-postgresql-compatibility/了解有趣的信息)。