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
私が望んでいた内部結合になります。
より良い解決策はありますか?おそらく「部分インデックスの統計」ですか?