web-dev-qa-db-ja.com

クエリに多数(18を超える)がある場合、GINインデックスは無視されますORステートメント

18 ORステートメントを実行すると、実行でGINインデックスが使用されないという問題があります。

これは私のインデックスです:

CREATE INDEX emailjobs_externalreferences_gin
ON vsko_mailer_api_prod.emailjobs USING gin
("externalReferences" jsonb_path_ops)
TABLESPACE pg_default;

これはクエリです:

explain analyze
select * from "emailjobs"
where "emailjobs"."$$meta.deleted" = false
  and ("externalReferences" @> '[{"href":"/responsibilities/pending/06ad562d-379a-4827-a9d3-1de179e29852"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/0e754454-db34-4ec2-8192-898f34928e80"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/0f93b24c-ee8f-4872-896c-9a75fcb904e0"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/10f38c74-6b6f-4298-819f-a2a2e61f23ce"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/127468cf-0bb4-41fe-8d5d-2886a4f0d4a4"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/297aefb9-e4aa-4b9e-9dcd-8687df1b200a"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/2e5c4b39-4375-49be-9bee-7b8106502c59"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/2f08f86c-696b-4f71-bbe3-51cf2bc74387"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/2f443528-b173-4522-bdb2-7c942112d781"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/2f8e87f6-4573-478d-925d-fca286cc6cee"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/318417fa-9c41-4377-b815-02f40147ce65"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/3b4cd61c-6adc-4b56-8519-5bd2612fb214"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/3e5ed89e-bfa4-47f9-a056-9817f8e91a4a"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/404a90d6-a6e8-4068-8d0c-904685705129"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/524a5dde-7245-4796-9cd5-1f1eee9b4f6a"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/5b4b6606-e3ec-49a4-8882-0faeb7d51f60"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/62e267f7-6720-4874-8c24-270465d7f171"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/64212e18-ba9e-4dc6-b35b-9bd66ec4d49a"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/64212e18-ba9e-4dc6-b35b-9bd66ec4d49a"}]'::jsonb)
order by "$$meta.created" asc,"key" asc
limit '500'

そしてその結果:

"Limit  (cost=0.08..8857.81 rows=500 width=1380) (actual time=766.232..1182.058 rows=49 loops=1)"
"  ->  Index Scan using emailjobs_ordered_created_and_keys on emailjobs  (cost=0.08..70064.73 rows=3955 width=1380) (actual time=766.230..1182.049 rows=49 loops=1)"
"        Filter: ((NOT "$$meta.deleted") AND (("externalReferences" @> '[{"href": "/responsibilities/pending/06ad562d-379a-4827-a9d3-1de179e29852"}]'::jsonb) OR ("externalReferences" @> '[{"href": "/responsibilities/pending/0e754454-db34-4ec2-8192-898f34928e80"}]'::jsonb) OR ("externalReferences" @> '[{"href": "/responsibilities/pending/0f93b24c-ee8f-4872-896c-9a75fcb904e0"}]'::jsonb) OR ("externalReferences" @> '[{"href": "/responsibilities/pending/10f38c74-6b6f-4298-819f-a2a2e61f23ce"}]'::jsonb) OR ("externalReferences" @> '[{"href": "/responsibilities/pending/127468cf-0bb4-41fe-8d5d-2886a4f0d4a4"}]'::jsonb) OR ("externalReferences" @> '[{"href": "/responsibilities/pending/297aefb9-e4aa-4b9e-9dcd-8687df1b200a"}]'::jsonb) OR ("externalReferences" @> '[{"href": "/responsibilities/pending/2e5c4b39-4375-49be-9bee-7b8106502c59"}]'::jsonb) OR ("externalReferences" @> '[{"href": "/responsibilities/pending/2f08f86c-696b-4f71-bbe3-51cf2bc74387"}]'::jsonb) OR ("externalReferences" @> '[{"href": "/responsibilities/pending/2f443528-b173-4522-bdb2-7c942112d781"}]'::jsonb) OR ("externalReferences" @> '[{"href": "/responsibilities/pending/2f8e87f6-4573-478d-925d-fca286cc6cee"}]'::jsonb) OR ("externalReferences" @> '[{"href": "/responsibilities/pending/318417fa-9c41-4377-b815-02f40147ce65"}]'::jsonb) OR ("externalReferences" @> '[{"href": "/responsibilities/pending/3b4cd61c-6adc-4b56-8519-5bd2612fb214"}]'::jsonb) OR ("externalReferences" @> '[{"href": "/responsibilities/pending/3e5ed89e-bfa4-47f9-a056-9817f8e91a4a"}]'::jsonb) OR ("externalReferences" @> '[{"href": "/responsibilities/pending/404a90d6-a6e8-4068-8d0c-904685705129"}]'::jsonb) OR ("externalReferences" @> '[{"href": "/responsibilities/pending/524a5dde-7245-4796-9cd5-1f1eee9b4f6a"}]'::jsonb) OR ("externalReferences" @> '[{"href": "/responsibilities/pending/5b4b6606-e3ec-49a4-8882-0faeb7d51f60"}]'::jsonb) OR ("externalReferences" @> '[{"href": "/responsibilities/pending/62e267f7-6720-4874-8c24-270465d7f171"}]'::jsonb) OR ("externalReferences" @> '[{"href": "/responsibilities/pending/64212e18-ba9e-4dc6-b35b-9bd66ec4d49a"}]'::jsonb) OR ("externalReferences" @> '[{"href": "/responsibilities/pending/64212e18-ba9e-4dc6-b35b-9bd66ec4d49a"}]'::jsonb)))"
"        Rows Removed by Filter: 216447"
"Planning time: 0.237 ms"
"Execution time: 1182.107 ms"

したがって、GINインデックスは使用していません。

しかし、私はターニングポイントを探しました。私が18以下の場合ORステートメントは、GINをうまく使用しているようです。

explain analyze
select * from "emailjobs"
where "emailjobs"."$$meta.deleted" = false
  and ("externalReferences" @> '[{"href":"/responsibilities/pending/06ad562d-379a-4827-a9d3-1de179e29852"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/0e754454-db34-4ec2-8192-898f34928e80"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/0f93b24c-ee8f-4872-896c-9a75fcb904e0"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/10f38c74-6b6f-4298-819f-a2a2e61f23ce"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/127468cf-0bb4-41fe-8d5d-2886a4f0d4a4"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/297aefb9-e4aa-4b9e-9dcd-8687df1b200a"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/2e5c4b39-4375-49be-9bee-7b8106502c59"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/2f08f86c-696b-4f71-bbe3-51cf2bc74387"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/2f443528-b173-4522-bdb2-7c942112d781"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/2f8e87f6-4573-478d-925d-fca286cc6cee"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/318417fa-9c41-4377-b815-02f40147ce65"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/3b4cd61c-6adc-4b56-8519-5bd2612fb214"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/3e5ed89e-bfa4-47f9-a056-9817f8e91a4a"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/404a90d6-a6e8-4068-8d0c-904685705129"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/524a5dde-7245-4796-9cd5-1f1eee9b4f6a"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/5b4b6606-e3ec-49a4-8882-0faeb7d51f60"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/62e267f7-6720-4874-8c24-270465d7f171"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/64212e18-ba9e-4dc6-b35b-9bd66ec4d49a"}]'::jsonb)
order by "$$meta.created" asc,"key" asc
limit '500'

結果:

"Limit  (cost=8938.34..8938.59 rows=500 width=1380) (actual time=23.443..23.455 rows=49 loops=1)"
"  ->  Sort  (cost=8938.34..8940.21 rows=3749 width=1380) (actual time=23.442..23.448 rows=49 loops=1)"
"        Sort Key: "$$meta.created", key"
"        Sort Method: quicksort  Memory: 123kB"
"        ->  Bitmap Heap Scan on emailjobs  (cost=2673.05..8900.97 rows=3749 width=1380) (actual time=23.000..23.326 rows=49 loops=1)"
"              Recheck Cond: (("externalReferences" @> '[{"href": "/responsibilities/pending/06ad562d-379a-4827-a9d3-1de179e29852"}]'::jsonb) OR ("externalReferences" @> '[{"href": "/responsibilities/pending/0e754454-db34-4ec2-8192-898f34928e80"}]'::jsonb) OR ("externalReferences" @> '[{"href": "/responsibilities/pending/0f93b24c-ee8f-4872-896c-9a75fcb904e0"}]'::jsonb) OR ("externalReferences" @> '[{"href": "/responsibilities/pending/10f38c74-6b6f-4298-819f-a2a2e61f23ce"}]'::jsonb) OR ("externalReferences" @> '[{"href": "/responsibilities/pending/127468cf-0bb4-41fe-8d5d-2886a4f0d4a4"}]'::jsonb) OR ("externalReferences" @> '[{"href": "/responsibilities/pending/297aefb9-e4aa-4b9e-9dcd-8687df1b200a"}]'::jsonb) OR ("externalReferences" @> '[{"href": "/responsibilities/pending/2e5c4b39-4375-49be-9bee-7b8106502c59"}]'::jsonb) OR ("externalReferences" @> '[{"href": "/responsibilities/pending/2f08f86c-696b-4f71-bbe3-51cf2bc74387"}]'::jsonb) OR ("externalReferences" @> '[{"href": "/responsibilities/pending/2f443528-b173-4522-bdb2-7c942112d781"}]'::jsonb) OR ("externalReferences" @> '[{"href": "/responsibilities/pending/2f8e87f6-4573-478d-925d-fca286cc6cee"}]'::jsonb) OR ("externalReferences" @> '[{"href": "/responsibilities/pending/318417fa-9c41-4377-b815-02f40147ce65"}]'::jsonb) OR ("externalReferences" @> '[{"href": "/responsibilities/pending/3b4cd61c-6adc-4b56-8519-5bd2612fb214"}]'::jsonb) OR ("externalReferences" @> '[{"href": "/responsibilities/pending/3e5ed89e-bfa4-47f9-a056-9817f8e91a4a"}]'::jsonb) OR ("externalReferences" @> '[{"href": "/responsibilities/pending/404a90d6-a6e8-4068-8d0c-904685705129"}]'::jsonb) OR ("externalReferences" @> '[{"href": "/responsibilities/pending/524a5dde-7245-4796-9cd5-1f1eee9b4f6a"}]'::jsonb) OR ("externalReferences" @> '[{"href": "/responsibilities/pending/5b4b6606-e3ec-49a4-8882-0faeb7d51f60"}]'::jsonb) OR ("externalReferences" @> '[{"href": "/responsibilities/pending/62e267f7-6720-4874-8c24-270465d7f171"}]'::jsonb) OR ("externalReferences" @> '[{"href": "/responsibilities/pending/64212e18-ba9e-4dc6-b35b-9bd66ec4d49a"}]'::jsonb))"
"              Filter: (NOT "$$meta.deleted")"
"              Heap Blocks: exact=62"
"              ->  BitmapOr  (cost=2673.05..2673.05 rows=3781 width=0) (actual time=22.922..22.922 rows=0 loops=1)"
"                    ->  Bitmap Index Scan on emailjobs_externalreferences_gin  (cost=0.00..148.32 rows=210 width=0) (actual time=1.283..1.283 rows=5 loops=1)"
"                          Index Cond: ("externalReferences" @> '[{"href": "/responsibilities/pending/06ad562d-379a-4827-a9d3-1de179e29852"}]'::jsonb)"
"                    ->  Bitmap Index Scan on emailjobs_externalreferences_gin  (cost=0.00..148.32 rows=210 width=0) (actual time=1.281..1.281 rows=2 loops=1)"
"                          Index Cond: ("externalReferences" @> '[{"href": "/responsibilities/pending/0e754454-db34-4ec2-8192-898f34928e80"}]'::jsonb)"
"                    ->  Bitmap Index Scan on emailjobs_externalreferences_gin  (cost=0.00..148.32 rows=210 width=0) (actual time=1.358..1.358 rows=5 loops=1)"
"                          Index Cond: ("externalReferences" @> '[{"href": "/responsibilities/pending/0f93b24c-ee8f-4872-896c-9a75fcb904e0"}]'::jsonb)"
"                    ->  Bitmap Index Scan on emailjobs_externalreferences_gin  (cost=0.00..148.32 rows=210 width=0) (actual time=1.196..1.196 rows=5 loops=1)"
"                          Index Cond: ("externalReferences" @> '[{"href": "/responsibilities/pending/10f38c74-6b6f-4298-819f-a2a2e61f23ce"}]'::jsonb)"
"                    ->  Bitmap Index Scan on emailjobs_externalreferences_gin  (cost=0.00..148.32 rows=210 width=0) (actual time=1.249..1.249 rows=5 loops=1)"
"                          Index Cond: ("externalReferences" @> '[{"href": "/responsibilities/pending/127468cf-0bb4-41fe-8d5d-2886a4f0d4a4"}]'::jsonb)"
"                    ->  Bitmap Index Scan on emailjobs_externalreferences_gin  (cost=0.00..148.32 rows=210 width=0) (actual time=1.312..1.312 rows=5 loops=1)"
"                          Index Cond: ("externalReferences" @> '[{"href": "/responsibilities/pending/297aefb9-e4aa-4b9e-9dcd-8687df1b200a"}]'::jsonb)"
"                    ->  Bitmap Index Scan on emailjobs_externalreferences_gin  (cost=0.00..148.32 rows=210 width=0) (actual time=1.291..1.291 rows=5 loops=1)"
"                          Index Cond: ("externalReferences" @> '[{"href": "/responsibilities/pending/2e5c4b39-4375-49be-9bee-7b8106502c59"}]'::jsonb)"
"                    ->  Bitmap Index Scan on emailjobs_externalreferences_gin  (cost=0.00..148.32 rows=210 width=0) (actual time=1.247..1.247 rows=5 loops=1)"
"                          Index Cond: ("externalReferences" @> '[{"href": "/responsibilities/pending/2f08f86c-696b-4f71-bbe3-51cf2bc74387"}]'::jsonb)"
"                    ->  Bitmap Index Scan on emailjobs_externalreferences_gin  (cost=0.00..148.32 rows=210 width=0) (actual time=1.284..1.284 rows=3 loops=1)"
"                          Index Cond: ("externalReferences" @> '[{"href": "/responsibilities/pending/2f443528-b173-4522-bdb2-7c942112d781"}]'::jsonb)"
"                    ->  Bitmap Index Scan on emailjobs_externalreferences_gin  (cost=0.00..148.32 rows=210 width=0) (actual time=1.261..1.261 rows=5 loops=1)"
"                          Index Cond: ("externalReferences" @> '[{"href": "/responsibilities/pending/2f8e87f6-4573-478d-925d-fca286cc6cee"}]'::jsonb)"
"                    ->  Bitmap Index Scan on emailjobs_externalreferences_gin  (cost=0.00..148.32 rows=210 width=0) (actual time=1.268..1.268 rows=5 loops=1)"
"                          Index Cond: ("externalReferences" @> '[{"href": "/responsibilities/pending/318417fa-9c41-4377-b815-02f40147ce65"}]'::jsonb)"
"                    ->  Bitmap Index Scan on emailjobs_externalreferences_gin  (cost=0.00..148.32 rows=210 width=0) (actual time=1.296..1.296 rows=3 loops=1)"
"                          Index Cond: ("externalReferences" @> '[{"href": "/responsibilities/pending/3b4cd61c-6adc-4b56-8519-5bd2612fb214"}]'::jsonb)"
"                    ->  Bitmap Index Scan on emailjobs_externalreferences_gin  (cost=0.00..148.32 rows=210 width=0) (actual time=1.223..1.223 rows=5 loops=1)"
"                          Index Cond: ("externalReferences" @> '[{"href": "/responsibilities/pending/3e5ed89e-bfa4-47f9-a056-9817f8e91a4a"}]'::jsonb)"
"                    ->  Bitmap Index Scan on emailjobs_externalreferences_gin  (cost=0.00..148.32 rows=210 width=0) (actual time=1.273..1.273 rows=5 loops=1)"
"                          Index Cond: ("externalReferences" @> '[{"href": "/responsibilities/pending/404a90d6-a6e8-4068-8d0c-904685705129"}]'::jsonb)"
"                    ->  Bitmap Index Scan on emailjobs_externalreferences_gin  (cost=0.00..148.32 rows=210 width=0) (actual time=1.287..1.287 rows=5 loops=1)"
"                          Index Cond: ("externalReferences" @> '[{"href": "/responsibilities/pending/524a5dde-7245-4796-9cd5-1f1eee9b4f6a"}]'::jsonb)"
"                    ->  Bitmap Index Scan on emailjobs_externalreferences_gin  (cost=0.00..148.32 rows=210 width=0) (actual time=1.240..1.240 rows=5 loops=1)"
"                          Index Cond: ("externalReferences" @> '[{"href": "/responsibilities/pending/5b4b6606-e3ec-49a4-8882-0faeb7d51f60"}]'::jsonb)"
"                    ->  Bitmap Index Scan on emailjobs_externalreferences_gin  (cost=0.00..148.32 rows=210 width=0) (actual time=1.255..1.255 rows=5 loops=1)"
"                          Index Cond: ("externalReferences" @> '[{"href": "/responsibilities/pending/62e267f7-6720-4874-8c24-270465d7f171"}]'::jsonb)"
"                    ->  Bitmap Index Scan on emailjobs_externalreferences_gin  (cost=0.00..148.32 rows=210 width=0) (actual time=1.310..1.310 rows=5 loops=1)"
"                          Index Cond: ("externalReferences" @> '[{"href": "/responsibilities/pending/64212e18-ba9e-4dc6-b35b-9bd66ec4d49a"}]'::jsonb)"
"Planning time: 0.249 ms"
"Execution time: 23.623 ms"

どのようにこのクエリを最適化して、より多くのORステートメント(少なくとも50のようですか?)

以下は、externalReferencesデータの例です。

"[{"href":"/responsibilities/pending/64212e18-ba9e-4dc6-b35b-9bd66ec4d49a"},{"href":"/sam/organisationalunits/4fc33e81-6a08-4be8-82b9-8822f77787d5"}]"

編集:

externalReferencesも空の配列である可能性があります。

4
Stefanvds

問題は、PostgreSQLがより多くのOR条件を指定するとより多くの行が返されると想定することです。そのため、ある時点で、インデックススキャンはこれ以上高速にならないと考えられます。

JSONの興味深い部分を抽出する関数を作成できます。

CREATE FUNCTION get_array(jsonb) RETURNS text[]
   LANGUAGE sql IMMUTABLE AS
$$SELECT array_agg(x->>'href') FROM jsonb_array_elements($1) AS v(x)$$;

次に、インデックスを作成できます

CREATE INDEX ON vsko_mailer_api_prod.emailjobs USING gin (get_array("externalReferences"));

そして、このようなクエリ:

... WHERE get_array("externalReferences")
          && ARRAY['/responsibilities/pending/06ad562d-379a-4827-a9d3-1de179e29852',
                   '/responsibilities/pending/0e754454-db34-4ec2-8192-898f34928e80',
                   ...
                  ]

「overlaps」演算子は必要なことを行う必要があります。

4
Laurenz Albe

さらにOR条件を追加すると、より多くの行が返されると見なされます。ORDERBYとLIMITがあるため、ある時点で、同じ順序付けを提供する別のインデックスを歩くと見なされますORDER BYおよびLIMITに達すると早期に停止するため、WHERE句を満たすすべての行を取得し、それらを順番に並べ替えてLIMITを適用するよりも高速です。

これを修正する最も簡単な方法は、ORDER BYに使用されているインデックスをスカンクすることです( "emailjobs_ordered_created_and_keys")。 「キー」が数値の場合、次のことができます。

order by "$$meta.created" asc,"key"+0 asc

またはテキストの場合、

order by "$$meta.created" asc,"key"||'' asc

これは実際の順序を変更しませんが、PostgreSQLがインデックスを使用してその順序を提供できることを認識しなくなります。

また、CTEを最適化フェンスとして使用して、制限を注文して適用する前に全選択を強制的に実行することもできます。

explain analyze
with t as (
select * from "emailjobs"
where "emailjobs"."$$meta.deleted" = false
  and ("externalReferences" @> '[{"href":"/responsibilities/pending/06ad562d-379a-4827-a9d3-1de179e29852"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/0e754454-db34-4ec2-8192-898f34928e80"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/0f93b24c-ee8f-4872-896c-9a75fcb904e0"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/10f38c74-6b6f-4298-819f-a2a2e61f23ce"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/127468cf-0bb4-41fe-8d5d-2886a4f0d4a4"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/297aefb9-e4aa-4b9e-9dcd-8687df1b200a"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/2e5c4b39-4375-49be-9bee-7b8106502c59"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/2f08f86c-696b-4f71-bbe3-51cf2bc74387"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/2f443528-b173-4522-bdb2-7c942112d781"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/2f8e87f6-4573-478d-925d-fca286cc6cee"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/318417fa-9c41-4377-b815-02f40147ce65"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/3b4cd61c-6adc-4b56-8519-5bd2612fb214"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/3e5ed89e-bfa4-47f9-a056-9817f8e91a4a"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/404a90d6-a6e8-4068-8d0c-904685705129"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/524a5dde-7245-4796-9cd5-1f1eee9b4f6a"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/5b4b6606-e3ec-49a4-8882-0faeb7d51f60"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/62e267f7-6720-4874-8c24-270465d7f171"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/64212e18-ba9e-4dc6-b35b-9bd66ec4d49a"}]'::jsonb
   OR  "externalReferences" @> '[{"href":"/responsibilities/pending/64212e18-ba9e-4dc6-b35b-9bd66ec4d49a"}]'::jsonb
    )
)
select * from t
order by "$$meta.created" asc,"key" asc
limit '500'

V12以降、with t as materializedと記述しない限り、これは最適化フェンスではなくなりました。

なぜPostgreSQLがそもそも間違っているのですか? JSONオブジェクトには統計が収集されていないため、PostgreSQLは、@>演算子に一致する行数に関する一般的な推定値を使用する必要があります。約40倍過大評価していることがわかります。これは、並べ替えルートに従うと、並べ替える行が40倍多くなると考え、40倍少なくなると考えるので、二重の奇妙な動作です。それがそのルートをとる場合、(LIMITが開始する前に)スキャンするために既に順序付けられたインデックスの。これを修正する可能性がある1つの方法は、JSONBを通常のPostgreSQL配列にマッピングすることです。その方法でそれらをテーブルに格納するか、ローレンツが概説するように関数インデックスを作成できます。ただし、私の手では、これはJSONBよりも行の見積もりの​​ほうがさらに悪かった:理由により、most_common_elems列がNULLになった すでに調査済み

したがって、少なくともPostgreSQLの将来のバージョンでより良いソリューションが提供されるまでは、最初に説明した迅速で汚いハックを使用します。

2
jjanes