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 行
订单_附录:
- 每个订单一行
我的问题是:
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
将导致我想要的内部连接。
有更好的解决方案吗?也许是“部分索引统计”?