0

PostgreSQL バージョン: 9.3.13

次のテーブル、インデックス、およびデータを検討してください。

CREATE TABLE orders (
 order_id bigint,
 status smallint,
 owner int,
 CONSTRAINT orders_pkey PRIMARY KEY (order_id)
)

CREATE INDEX owner_index ON orders
  USING btree
 (owner) WHERE status > 0;

CREATE TABLE orders_appendix (
  order_id bigint,
  note text
)

データ

注文:

  • (ID、0、1337) * 1000000 行

  • (ID、10、1337) * 1000 行

  • (ID、10、777) * 1000 行

orders_appendix:

  • 注文ごとに 1 行

私の問題は次のとおりです。

select * from orders where owner=1337 and status>0

クエリ プランナーは行数を 1000000 と見積もっていましたが、実際の行数は 1000 です。

より複雑な次のクエリでは:

SELECT note FROM orders JOIN orders_appendix using (order_id)
WHERE owner=1337 AND status>0

内部結合 (少数の行に適しています) を使用する代わりに、ビットマップ結合 + orders_appendix での完全なテーブル スキャンを選択しますが、これは非常に低速です。

条件が「owner=777」の場合、代わりに望ましい内部結合が選択されます。

AFAIK postgresは各列の統計を個別に収集して考慮することしかできないため、統計のせいだと思います。

しかし、もし私が...

CREATE INDEX onwer_abs ON orders (abs(owner)) where status>0;

さて、少し変更されたクエリ...

SELECT note FROM orders JOIN rders_appendix using (order_id)
WHERE abs(owner)=1337 AND status>0

私が望んでいた内部結合になります。


より良い解決策はありますか?おそらく「部分インデックスの統計」ですか?

4

0 に答える 0