2017-01-11 4 views
0

アプリケーションPostgreSQL DBに最適なインデックス構成を設計しようとしていますが、PK列のインデックスを手動で作成すると推定パフォーマンスが大幅に向上します。最初のアイデアはhere, the first commentです。PostgreSQLの組み込みインデックスと手動による作成の比較:パフォーマンスの側面

誰かが説明してもらえ:

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

マニュアルUNIQ UEインデックスは、あなたが通常のを見てすることができる唯一の

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

コスト見積もりは同じです。測定された実行時間は意味がある方法で比較するには小さすぎます。どのくらいの頻度でこのベンチマークを実行しましたか? 「キャッシュ/コールドスタート」歪みがないことを確認しましたか? – Thilo

+1

同じ列と同じデータ・セットの場合、手動で作成されたBツリー索引と、一意制約があるかどうかには違いがありません。 – Thilo

+0

自動的に作成された索引を使用しない場合のユースケースは、アプリケーションの方が優れていると判断した*構造的に異なる*索引がすでにある場合です。たとえば、すでにインデックス(id、tx_date、type)を持っている場合、そのインデックスをプライマリキーの適用に使用することができます。したがって、idだけにインデックスを追加したくない場合もあります。 – Thilo

答えて

3

は、システム内のジッタの影響します。

私はあなたが合理的なサイズのデータ​​セットを取ってから、何百万ものテストを実行して大きな違いがあるかどうかを確認することをお勧めします。

よくテストされていますが、より統計的に有意なデータセットが必要だと思います。

(btw興味深い情報についてはhttps://aws.amazon.com/blogs/aws/amazon-aurora-update-postgresql-compatibility/のジッタチャートを参照してください)。

関連する問題