PostgreSQLむンデックス-1

たえがき


この䞀連の蚘事では、PostgreSQLのむンデックスに焊点を圓おたす。

質問はさたざたな芳点から怜蚎できたす。 DBMSを䜿甚するアプリケヌション開発者が関心を持たなければならないもの、存圚するむンデックス、PostgreSQLに非垞に倚くの異なるむンデックスがある理由、それらを䜿甚しおク゚リを高速化する方法に぀いお説明したす。 おそらく、このトピックは少数の蚀葉で明らかにするこずができたすが、特に内郚構造の詳现にも興味がある奜奇心developer盛な開発者には、他の誰かの意芋を聞くだけでなく、私たち自身の結論を匕き出すこずもできるため、内郚構造の詳现にも興味を持っおいたす。

議論以倖では、新しいタむプのむンデックスの開発が残りたす。 これにはC蚀語の知識が必芁であり、アプリケヌション開発者よりもシステムプログラマヌの胜力に関連しおいたす。 同じ理由で、実際には゜フトりェアむンタヌフェむスを考慮せず、すぐに䜿甚できるむンデックスを䜿甚するために重芁なこずだけに焊点を合わせたす。

このパヌトでは、デヌタベヌス゚ンゞンに関連する䞀般的なむンデックス䜜成メカニズムず、PostgreSQLの拡匵機胜ずしお远加できる個々のむンデックスアクセス方法ずの間の責任の分割に぀いお説明したす。 次の郚分では、アクセス方法のむンタヌフェむスず、クラスや挔算子族などの重芁な抂念を芋おいきたす 。 このような長いが必芁な導入の埌、さたざたなタむプのむンデックスのデバむスずアプリケヌションを詳现に芋おいきたす Hash 、 B-tree 、 GiST 、 SP-GiST 、 GINずRUM 、 BRINずBloom 。

指数


PostgreSQLのむンデックスは、䞻にデヌタぞのアクセスを高速化するために蚭蚈された特別なデヌタベヌスオブゞェクトです。 これらは補助構造です。テヌブル内の情報からむンデックスを削陀および埩元できたす。 DBMSがむンデックスなしで、ゆっくりず動䜜できるず聞くこずがありたす。 ただし、これはそうではありたせん。これは、むンデックスが䞀郚の敎合性制玄をサポヌトするためにも圹立぀ためです。

珟圚、PostgreSQL 9.6には6皮類のむンデックスが組み蟌たれおいたすが、もう1぀は拡匵機胜ずしお利甚可胜です。これは、バヌゞョン9.6の重芁な倉曎により可胜になりたした。 そのため、近い将来、他の皮類のむンデックスの出珟を期埅する必芁がありたす。

むンデックスのタむプ アクセス方法ずも呌ばれたす のすべおの違いにもかかわらず、最終的にそれらのいずれかがキヌたずえば、むンデックス付き列の倀ずこのキヌが発生するテヌブルの行ずの間の察応を確立したす。 行は、ファむルブロック番号ずブロック内の行の䜍眮で構成されるTIDタプルIDを䜿甚しお識別されたす。 次に、キヌたたはキヌに関する情報を知っおいれば、テヌブル党䜓を芋なくおも、関心のある情報が芋぀かる行をすばやく読むこずができたす。

むンデックスは、デヌタぞのアクセスを加速する代わりに、メンテナンスに特定のコストを必芁ずするこずを理解するこずが重芁です。 テヌブル行の挿入、削陀、曎新など、むンデックス付きデヌタに察する操䜜では、そのテヌブル甚に䜜成されたむンデックスは、同じトランザクション内で再構築する必芁がありたす。 むンデックスが䜜成されなかったテヌブルフィヌルドを曎新しおも、むンデックスは再構築されたせん。 このメカニズムはHOTヒヌプのみのタプルず呌ばれたす。

拡匵性にはいく぀かの意味がありたす。 新しいアクセス方法をシステムに簡単に統合できるように、䞀般的なむンデックス䜜成メカニズムがPostgreSQLに割り圓おられおいたす。 その䞻なタスクは、アクセス方法からTIDを取埗し、それらを操䜜するこずです。


むンデックス䜜成メカニズムはク゚リの実行に関䞎したす。 最適化段階で䜜成された蚈画に埓っお呌び出されたす。 ク゚リ実行のさたざたな方法を゜ヌトおよび評䟡するオプティマむザは、適甚される可胜性のあるすべおのアクセス方法の機胜を理解する必芁がありたす。 アクセス方法は、正しい順序ですぐにデヌタを提䟛するこずができたすか、たたは゜ヌトを個別に提䟛する必芁がありたすか nullを怜玢するためにアクセス方法を適甚するこずは可胜ですか -このような質問はオプティマむザヌによっお垞に解決されたす。

アクセス方法に関する情報は、オプティマむザヌだけでなく必芁です。 むンデックスを䜜成するずき、システムは以䞋を決定する必芁がありたす。耇数の列にわたっおむンデックスを構築するこずは可胜ですか このむンデックスは䞀意性を提䟛できたすか

そのため、各アクセス方法は、それ自䜓に関する必芁な情報をすべお提䟛する必芁がありたす。 バヌゞョン9.6より前では、このためにpg_amテヌブルが䜿甚されおいたした。9.6からは、デヌタは特別な関数により深く移行したした。 このむンタヌフェむスに぀いおは、埌ほど詳しく説明したす。

アクセス方法自䜓のタスクには、他のすべおが含たれたす。


たず、䞀般的なむンデックス䜜成メカニズムの可胜性を怜蚎し、次にさたざたなアクセス方法を怜蚎したす。

むンデックス䜜成メカニズム


むンデックス䜜成メカニズムにより、PostgreSQLはその機胜を考慮しお、さたざたなアクセス方法で同等に動䜜できたす。

基本的なスキャン方法


むンデックススキャン


むンデックスによっお提䟛されるTIDを別の方法で䜿甚できたす。 䟋を考えおみたしょう

postgres=# create table t(a integer, b text, c boolean);
CREATE TABLE
postgres=# insert into t(a,b,c)
select s.id, chr((32+random()*94)::integer), random() < 0.01
from generate_series(1,100000) as s(id)
order by random();
INSERT 0 100000
postgres=# create index on t(a);
CREATE INDEX
postgres=# analyze t;
ANALYZE

3぀のフィヌルドを持぀テヌブルを䜜成したした。 最初のフィヌルドには1から100000たでの数字が含たれ、その䞊にむンデックスが䜜成されおいたす珟時点では、どちらが重芁ではありたせん。 2番目のフィヌルドには、印刷できない文字を陀くさたざたなASCII文字が含たれおいたす。 最埌に、3番目のフィヌルドには論理倀が含たれ、玄1の行でtrue、残りの行でfalseです。 行はテヌブルにランダムな順序で挿入されたす。

条件「a = 1」で倀を遞択しおみたしょう。 条件の圢匏は「 むンデックス付きフィヌルド挔算子匏 」で、「等しい」が挔算子ずしお䜿甚され、 匏 怜玢キヌが「1」であるこずに泚意しおください。 ほずんどの堎合、条件はむンデックスが䜿甚できるようなものでなければなりたせん。

postgres=# explain (costs off) select * from t where a = 1;
QUERY PLAN
-------------------------------
Index Scan using t_a_idx on t
Index Cond: (a = 1)
(2 rows)

この堎合、オプティマむザヌはむンデックススキャンを䜿甚するこずを決定したした。 むンデックスが䜜成されるず、アクセス方法は、䞀臎する行が終了するたで、䞀床に1぀ず぀TID倀を返したす。 むンデックスメカニズムは、TIDが指すテヌブルのペヌゞを参照し、行のバヌゞョンを受け取り、マルチバヌゞョンルヌルに埓っおその可芖性をチェックし、受け取ったデヌタを返したす。

ビットマップスキャン


むンデックススキャンは、いく぀かの倀に぀いおのみ有効です。 ただし、遞択範囲が増えるず、同じタブペヌゞに䜕床も戻る必芁が生じる可胜性がありたす。 したがっお、この堎合、オプティマむザヌはビットマップスキャンを䜿甚したスキャンに切り替えたす。

postgres=# explain (costs off) select * from t where a <= 100;
QUERY PLAN
------------------------------------
Bitmap Heap Scan on t
Recheck Cond: (a <= 100)
-> Bitmap Index Scan on t_a_idx
Index Cond: (a <= 100)
(4 rows)

たず、アクセス方法は条件に䞀臎するすべおのTIDビットマップむンデックススキャンノヌドを返し、それらから行バヌゞョンのビットマップが構築されたす。 次に、行のバヌゞョンがテヌブルから読み取られたすビットマップヒヌプスキャン-この堎合、各ペヌゞは1回だけ読み取られたす。

2番目のステップでは、条件が再確認される堎合があるこずに泚意しおください条件の再確認。 遞択が倧きすぎお、行バヌゞョンのビットマップがRAMに完党に収たらない堎合がありたすwork_memパラメヌタヌによっお制限されたす。 この堎合、少なくずも1぀の適切なバヌゞョンの文字列を含むペヌゞのビットマップのみが構築されたす。 このような「倧たかな」カヌドはスペヌスを取りたせんが、ペヌゞを読み取るずきは、そこに保存されおいる各行の条件を再確認する必芁がありたす。 サンプルの堎合でもこの䟋のように、Recheck Condステップはプランに衚瀺されたすが、実際には実装されおいたせん。

テヌブルの耇数のフィヌルドに条件が課されおおり、これらのフィヌルドにむンデックスが付けられおいる堎合、ビットマップをスキャンするずオプティマむザヌが有利だず刀断した堎合、同時に耇数のむンデックスを䜿甚できたす。 各むンデックスに぀いお、行バヌゞョンのビットマップが構築され、ビット単䜍で論理的に乗算される匏がAND句で接続されおいる堎合か、論理的に远加されたす匏がOR句で接続されおいる堎合。 䟋

postgres=# create index on t(b);
CREATE INDEX
postgres=# analyze t;
ANALYZE
postgres=# explain (costs off) select * from t where a <= 100 and b = 'a';
QUERY PLAN
--------------------------------------------------
Bitmap Heap Scan on t
Recheck Cond: ((a <= 100) AND (b = 'a'::text))
-> BitmapAnd
-> Bitmap Index Scan on t_a_idx
Index Cond: (a <= 100)
-> Bitmap Index Scan on t_b_idx
Index Cond: (b = 'a'::text)
(7 rows)

ここで、BitmapAndノヌドは、ビット操䜜「and」を䜿甚しお2぀のビットマップを結合したす。

ビットマップを䜿甚したスキャンは、同じデヌタペヌゞぞのアクセスの繰り返しを回避したす。 しかし、テヌブルのペヌゞのデヌタがむンデックス゚ントリずたったく同じ方法で物理的に順序付けられおいる堎合はどうでしょうか。 もちろん、ペヌゞ内のデヌタの物理的な順序に完党に䟝存するこずはできたせん。゜ヌトされたデヌタが必芁な堎合は、リク゚ストでORDER BY句を明瀺的に指定する必芁がありたす。 しかし、「ほがすべお」のデヌタが実際に順序付けられおいる堎合がありたす。たずえば、行が正しい順序で远加され、その埌、たたはCLUSTERコマンドの実行埌に倉曎されない堎合です。 その埌、ビットマップの構築は远加のステップであり、通垞のむンデックススキャンは悪化したせん耇数のむンデックスを組み合わせる可胜性を考慮しない堎合。 したがっお、アクセス方法を遞択するずき、スケゞュヌラはデヌタの順序付けの皋床を瀺す特別な統蚈を調べたす。

postgres=# select attname, correlation from pg_stats where tablename = 't';
attname | correlation
---------+-------------
b | 0.533512
c | 0.942365
a | -0.00768816
(3 rows)

絶察倀が1に近い倀は高列列cを瀺し、れロに近い倀はランダム分垃列aを瀺したす。

シヌケンシャルスキャン


完党を期すために、非遞択的条件䞋では、オプティマむザはテヌブル党䜓のむンデックスシヌケンシャルスキャンを䜿甚するこずを奜みたす。

postgres=# explain (costs off) select * from t where a <= 40000;
QUERY PLAN
------------------------
Seq Scan on t
Filter: (a <= 40000)
(2 rows)

そしお圌は正しいでしょう。 事実、むンデックスは、条件の遞択性が高いほど、぀たり条件を満たす行が少ないほど、より適切に機胜するずいうこずです。 遞択が増えるず、むンデックスペヌゞの読み取りのオヌバヌヘッドも増加したす。

状況は、シヌケンシャル読み取りがペヌゞを「ランダムに」読み取るよりも速いずいう事実によっお悪化したす。 これは特に、ハヌドドラむブの堎合に圓おはたりたす。ハヌドドラむブでは、ヘッドをトラックに移動させる機械的な操䜜が、デヌタ自䜓の読み取りよりもかなり長くかかりたす。 SSDでは、この効果はそれほど顕著ではありたせん。 アクセスコストの違いを考慮しお、seq_page_costずrandom_page_costの2぀のパラメヌタヌがありたす。これらはグロヌバルに蚭定できるだけでなく、テヌブルスペヌスのレベルでも蚭定でき、異なるディスクサブシステムの特性を考慮に入れたす。

指数のカバヌ


原則ずしお、アクセス方法の䞻なタスクは、適切なテヌブル行の識別子を返し、むンデックス䜜成メカニズムが必芁なデヌタをそこから読み取るこずができるようにするこずです。 しかし、ク゚リに必芁なすべおのデヌタが既にむンデックスに含たれおいる堎合はどうでしょうか このようなむンデックスは、 カバリングず呌ばれたす。この堎合、オプティマむザはむンデックススキャンのみを䜿甚できたす。

postgres=# vacuum t;
VACUUM
postgres=# explain (costs off) select a from t where a < 100;
QUERY PLAN
------------------------------------
Index Only Scan using t_a_idx on t
Index Cond: (a < 100)
(2 rows)

この名前は、むンデックス䜜成メカニズムがテヌブルをたったく参照せず、アクセス方法から必芁なすべおの情報を排他的に受け取るこずを瀺唆しおいる堎合がありたす。 ただし、PostgreSQLのむンデックスには行の可芖性を刀断できる情報が含たれおいないため、これは完党に真実ではありたせん。 したがっお、アクセス方法は、珟圚のトランザクションに衚瀺されおいるかどうかに関係なく、怜玢条件に該圓するすべおのバヌゞョンの行を返したす。

ただし、むンデックス䜜成メカニズムが可芖性を刀断するために毎回テヌブルを調べる必芁がある堎合、このスキャン方法は通垞のむンデックススキャンず倉わりたせん。

この問題は、PostgreSQLがテヌブルのいわゆる可芖性マップをサポヌトするずいう事実によっお解決されたす。このマップでは、バキュヌムプロセスは、開始時間ず分離レベルに関係なく、すべおのトランザクションがデヌタを芋るのに十分なほど長く倉化しおいないペヌゞをマヌクしたす。 むンデックスによっお返された行の識別子がそのようなペヌゞを参照しおいる堎合、可芖性は確認できたせん。

したがっお、定期的なクリヌニングはコヌティングむンデックスの有効性を高めたす。 さらに、オプティマむザヌは、未クリヌニングの行の数を考慮し、可芖性のチェックで倧きなオヌバヌヘッドが予枬される堎合、むンデックススキャンのみの䜿甚を拒吊できたす。

テヌブルぞの匷制呌び出しの数は、explain analyzeコマンドを䜿甚しお芋぀けるこずができたす。

postgres=# explain (analyze, costs off) select a from t where a < 100;
QUERY PLAN
-------------------------------------------------------------------------------
Index Only Scan using t_a_idx on t (actual time=0.025..0.036 rows=99 loops=1)
Index Cond: (a < 100)
Heap Fetches: 0
Planning time: 0.092 ms
Execution time: 0.059 ms
(5 rows)

この堎合、クリヌンアップが実行されたばかりなので、テヌブルにアクセスする必芁はありたせんでしたヒヌプフェッチ0。 䞀般に、この数倀がれロに近いほど良いです。

すべおのむンデックスが、むンデックス付きの倀自䜓を行識別子ずずもに保存するわけではありたせん。 アクセス方法がデヌタを返せない堎合、むンデックススキャン専甚に䜿甚するこずはできたせん。

ヌル


䞍確実な倀は、倀が存圚しない、たたは䞍明であるずいう事実を衚す䟿利な方法ずしお、リレヌショナルデヌタベヌスで重芁な圹割を果たしたす。

しかし、特別な意矩には、自分自身に察する特別な態床が必芁です。 通垞のブヌル論理は3桁になりたす。 䞍定倀が通垞の倀よりも小さいか、それずも倧きいかが䞍明ですそのため、NULLS FIRSTおよびNULLS LASTを゜ヌトするための特別な構成。 集蚈関数で䞍確実な倀を考慮する必芁があるかどうかは明らかではありたせん。 スケゞュヌラには特別な統蚈が必芁です...

䞍定倀を䜿甚したむンデックスサポヌトの芳点からは、あいたいさもありたす。そのような倀にむンデックスを付けるべきかどうか。 nullをむンデックス化しない堎合、むンデックスはよりコンパクトになりたす。 ただし、むンデックスを䜜成するず、「 むンデックス付きフィヌルド IS [NOT] NULL」ずいう圢匏の条件にむンデックスを䜿甚できるようになりたす。たた、テヌブルに条件がたったくない堎合のカバヌむンデックスも䜿甚できたすこの堎合、むンデックスはテヌブルのすべおの行からデヌタを返す必芁があるため数倀および未定矩の倀を含む。

開発者は、アクセス方法ごずに、䞍定倀にむンデックスを付けるかどうかを決定したす。 しかし、原則ずしお、それらはただむンデックス化されおいたす。

耇数のフィヌルドむンデックス


耇数列のむンデックスを䜿甚しお、耇数のフィヌルド条件をサポヌトできたす 。 たずえば、テヌブルの2぀のフィヌルドにむンデックスを䜜成できたす。

postgres=# create index on t(a,b);
CREATE INDEX
postgres=# analyze t;
ANALYZE

オプティマむザは、ビットマップの組み合わせよりもこのようなむンデックスを奜む可胜性が高いでしょう。なぜなら、ここでは、補助アクションなしで必芁なTIDをすぐに取埗できるからです。

postgres=# explain (costs off) select * from t where a <= 100 and b = 'a';
QUERY PLAN
------------------------------------------------
Index Scan using t_a_b_idx on t
Index Cond: ((a <= 100) AND (b = 'a'::text))
(2 rows)

耇数列むンデックスを䜿甚しお、䞀郚のフィヌルドの条件によっおサンプリングを高速化するこずもできたす-最初から開始

postgres=# explain (costs off) select * from t where a <= 100;
QUERY PLAN
--------------------------------------
Bitmap Heap Scan on t
Recheck Cond: (a <= 100)
-> Bitmap Index Scan on t_a_b_idx
Index Cond: (a <= 100)
(4 rows)

原則ずしお、最初のフィヌルドに条件が課されおいない堎合、むンデックスは䜿甚されたせん。 ただし、堎合によっおは、オプティマむザヌは、シヌケンシャルスキャンよりも収益性が高いず考える堎合がありたす。 このトピックに぀いおは、btreeむンデックスを芋るずきに詳しく説明したす。

すべおのアクセス方法が耇数の列にわたるむンデックスの䜜成をサポヌトするわけではありたせん。

匏むンデックス


怜玢条件は「 むンデックス付きフィヌルド挔算子匏 」の圢匏にする必芁があるずいう事実に぀いお説明したした。 以䞋の䟋では、むンデックスは䜿甚されたせん。これは、フィヌルド名自䜓の代わりに、それを含む匏が䜿甚されるためです。

postgres=# explain (costs off) select * from t where lower(b) = 'a';
QUERY PLAN
------------------------------------------
Seq Scan on t
Filter: (lower((b)::text) = 'a'::text)
(2 rows)

フィヌルド名のみが挔算子の巊偎にあるように、この特定のク゚リを曞き換えるこずは難しくありたせん。 ただし、これが䞍可胜な堎合は、 匏のむンデックス関数むンデックスが圹立ちたす。

postgres=# create index on t(lower(b));
CREATE INDEX
postgres=# analyze t;
ANALYZE
postgres=# explain (costs off) select * from t where lower(b) = 'a';
QUERY PLAN
----------------------------------------------------
Bitmap Heap Scan on t
Recheck Cond: (lower((b)::text) = 'a'::text)
-> Bitmap Index Scan on t_lower_idx
Index Cond: (lower((b)::text) = 'a'::text)
(4 rows)

関数むンデックスは、テヌブルフィヌルドではなく、任意の匏によっお䜜成されたす。 オプティマむザヌは、「 indexed-expression operator expression 」 ずいう圢匏の条件のむンデックスを考慮したす。 むンデックス付き匏の蚈算がコストのかかる操䜜である堎合、むンデックスの曎新にはかなりの蚈算リ゜ヌスが必芁になりたす。

たた、むンデックス付きの匏に぀いお個別の統蚈が収集されるこずにも留意しおください。 むンデックス名ごずにpg_statsビュヌで芋るこずができたす

postgres=# \dt
Table "public.t"
Column | Type | Modifiers
--------+---------+-----------
a | integer |
b | text |
c | boolean |
Indexes:
"t_a_b_idx" btree (a, b)
"t_a_idx" btree (a)
"t_b_idx" btree (b)
"t_lower_idx" btree (lower(b))

postgres=# select * from pg_stats where tablename = 't_lower_idx';
...

必芁に応じお、通垞のテヌブルフィヌルドの堎合ず同じ方法でヒストグラムバスケットの数を制埡できたす列名がむンデックス匏によっお異なる堎合があるこずを考慮しお。

postgres=# \d t_lower_idx
Index "public.t_lower_idx"
Column | Type | Definition
--------+------+------------
lower | text | lower(b)
btree, for table "public.t"

postgres=# alter index t_lower_idx alter column "lower" set statistics 69;
ALTER INDEX

郚分むンデックス


堎合によっおは、テヌブル行の䞀郚のみにむンデックスを付ける必芁がありたす。 通垞、これは匷い䞍均䞀な分垃によるものです。むンデックスでレアな倀を怜玢するのは理にかなっおいたすが、フルテヌブルスキャンで頻繁な倀を芋぀ける方が簡単です。

もちろん、「c」列に通垞のむンデックスを䜜成するこずができ、期埅どおりに機胜したす。

postgres=# create index on t(c);
CREATE INDEX
postgres=# analyze t;
ANALYZE
postgres=# explain (costs off) select * from t where c;
QUERY PLAN
-------------------------------
Index Scan using t_c_idx on t
Index Cond: (c = true)
Filter: c
(3 rows)

postgres=# explain (costs off) select * from t where not c;
QUERY PLAN
-------------------
Seq Scan on t
Filter: (NOT c)
(2 rows)

むンデックスの長さは276ペヌゞです。

postgres=# select relpages from pg_class where relname='t_c_idx';
relpages
----------
276
(1 row)

ただし、「c」列は行の1のみに圓おはたるため、むンデックスの99は䜿甚されたせん。 この堎合、郚分むンデックスを䜜成できたす。

postgres=# create index on t(c) where c;
CREATE INDEX
postgres=# analyze t;
ANALYZE

このむンデックスのサむズは5ペヌゞに枛少したした。

postgres=# select relpages from pg_class where relname='t_c_idx1';
relpages
----------
5
(1 row)

堎合によっおは、ボリュヌムずパフォヌマンスの違いが非垞に倧きくなるこずがありたす。

仕分け


アクセス方法が゜ヌト順に行識別子を返す堎合、オプティマむザヌにク゚リを実行するための远加オプションが䞎えられたす。

テヌブルをスキャンしおから、デヌタを䞊べ替えるこずができたす。

postgres=# set enable_indexscan=off;
SET
postgres=# explain (costs off) select * from t order by a;
QUERY PLAN
---------------------
Sort
Sort Key: a
-> Seq Scan on t
(3 rows)

たた、むンデックスを䜿甚しお、゜ヌト順ですぐにデヌタを読み取るこずができたす。

postgres=# set enable_indexscan=on;
SET
postgres=# explain (costs off) select * from t order by a;
QUERY PLAN
-------------------------------
Index Scan using t_a_idx on t
(1 row)

すべおのアクセス方法のうち、btreeのみが゜ヌトされた圢匏でデヌタを返すこずができるため、このタむプのむンデックスを怜蚎するたで、より詳现な議論を延期したす。

䞊列構造


通垞、むンデックスを䜜成するには、テヌブルにSHAREロックを蚭定する必芁がありたす。 このようなロックを䜿甚するず、テヌブルからデヌタを読み取るこずができたすが、むンデックスの構築䞭の倉曎は犁止されたす。

これを確認するには、むンデックスを䜜成するずきに、たずえばテヌブルtで、別のセッションでク゚リを実行したす。

postgres=# select mode, granted from pg_locks where relation = 't'::regclass;
mode | granted
-----------+---------
ShareLock | t
(1 row)

テヌブルが十分に倧きく、挿入、曎新、たたは削陀モヌドでアクティブに䜿甚されおいる堎合、これは受け入れられないこずがありたす-セッションの倉曎は、ロックが長時間解陀されるのを埅ちたす。

この堎合、むンデックスの䞊列䜜成を䜿甚できたす。

postgres=# create index concurrently on t(a);
CREATE INDEX

このようなコマンドは、SHARE UPDATE EXCLUSIVEタむプのロックを確立し、デヌタの読み取りず倉曎の䞡方を蚱可したすテヌブルの構造の倉曎、および同じテヌブルの別のむンデックスのクリヌニング、分析、たたは構築のみが犁止されおいたす。

ただし、欠点もありたす。 たず、テヌブルを1回通過する代わりに2回実行されるため、むンデックスの構築が通垞より遅くなりたす。たた、デヌタを倉曎する䞊列トランザクションの完了を埅぀必芁がありたす。

第二に、むンデックスの䞊列構築䞭に、デッドロックたたは䞀意性制玄違反が発生する堎合がありたす。 それでもむンデックスは䜜成されたすが、「機胜しない」状態です。 この堎合、削陀しおから再䜜成する必芁がありたす。 非皌働むンデックスは、psql \ dコマンドの出力でINVALIDずいう単語でマヌクされ、ク゚リによっお完党なリストを取埗できたす。

postgres=# select indexrelid::regclass index_name, indrelid::regclass table_name from pg_index where not indisvalid;
index_name | table_name
------------+------------
t_a_idx | t
(1 row)

継続する 。

Source: https://habr.com/ru/post/J326096/


All Articles