PostgreSQL索引使用加入

时间:2016-01-20 17:29:55

标签: postgresql indexing postgresql-performance

有很多关于索引使用的帖子,我试图理解,但我希望有人可以帮助解决我的具体问题。我有一张桌子:

CREATE TABLE f4111
(
  costcenter_ilmcu character varying(12), -- Business Unit
  documenttype_ildct character varying(2), -- Document Type
  ordertype_ildcto character varying(2), -- Order Type
  documentorderinvoicee_ildoco numeric, -- Document (Order No Invoice etc.)
  datetransactionjulian_iltrdj date, -- Date - Order/Transaction
  uniquekeyidinternal_ilukid numeric NOT NULL, -- Unique Key ID (Internal)
  CONSTRAINT f4111_pk PRIMARY KEY (uniquekeyidinternal_ilukid)
);

此表有数亿条记录,因此实际内容按年度分区分开:

create table f4111_2011 (
  constraint f4111_2011_ck1 check
      (datetransactionjulian_iltrdj between '2011-01-01' and '2011-12-31')
) inherits (f4111);

每年都有其中一个,可以追溯到很久。每个分区都有以下索引:

CREATE INDEX f4111_2011_idx5 ON f4111_2011 (documenttype_ildct, ordertype_ildcto);
CREATE INDEX f4111_2011_idx6 ON f4111_2011 (documentorderinvoicee_ildoco);

我的目标是为此表中的15,000个左右工单完成最短交易日期:

create table open_work_orders (
  wo numeric not null
)

这有效:

insert into earliest_transaction_dates
SELECT 
  v.documentorderinvoicee_ildoco, min (v.datetransactionjulian_iltrdj)
FROM 
  f4111 v
  join work_orders w on
    v.documentorderinvoicee_ildoco = w.wo
WHERE
  v.documenttype_ildct = 'IM' and
  v.costcenter_ilmcu = '1AM' and
  v.ordertype_ildcto = 'WO' and
  v.datetransactionjulian_iltrdj >= '2011-01-01' -- to invoke check constraint
group by
  v.documentorderinvoicee_ildoco;

但要产生15,000个预期结果需要9分钟。它似乎没有使用索引f4111_2011_idx6

这违背了我所珍视的一切,但当我这样做时:

for work_order in select work_order_id from work_orders
loop
  insert into earliest_transaction_dates
  SELECT 
    work_order, min (v.datetransactionjulian_iltrdj)
  FROM 
    f4111 v
  WHERE
    v.documenttype_ildct = 'IM' and
    v.costcenter_ilmcu = '1AM' and
    v.ordertype_ildcto = 'WO' and
    v.documentorderinvoicee_ildoco = work_order and
    v.datetransactionjulian_iltrdj >= '2011-01-01';
 end loop;

确实使用索引并在2:14结束。

我意识到我在这里缺少一些基本的东西,但有没有办法让查询的9分钟版本使用documentorderinvoicee_ildoco上的索引?

我在9.5.0(太棒了,顺便说一句),我的所有统计数据都是最新的。

---编辑---

根据请求,我添加了以下附加信息。

  • 版本:9.5.0
  • 基数:
    • open_work_orders:15,422条记录
    • f4111:约78,000,000条记录
    • f4111分区:每个
    • 平均8,000,000条记录

为了展示手头的问题,我列出的查询是缩写的。每个表实际上都有相当多的字段和更多的索引。我只列出了足以证明问题的字段/索引。

解释计划:

GroupAggregate  (cost=2071976.16..2101248.07 rows=21992 width=13)
  Group Key: v.documentorderinvoicee_ildoco
  ->  Merge Join  (cost=2071976.16..2096083.48 rows=988933 width=13)
        Merge Cond: (((w.wo)::numeric) = v.documentorderinvoicee_ildoco)
        ->  Sort  (cost=1584.03..1622.58 rows=15422 width=4)
              Sort Key: ((w.wo)::numeric)
              ->  Seq Scan on open_work_order_1am w  (cost=0.00..511.22 rows=15422 width=4)
        ->  Materialize  (cost=2070392.13..2077443.30 rows=1410233 width=13)
              ->  Sort  (cost=2070392.13..2073917.71 rows=1410233 width=13)
                    Sort Key: v.documentorderinvoicee_ildoco
                    ->  Append  (cost=0.00..1902253.44 rows=1410233 width=13)
                          ->  Seq Scan on f4111_view v  (cost=0.00..0.00 rows=1 width=40)
                                Filter: ((datetransactionjulian_iltrdj >= '2011-01-01 00:00:00'::timestamp without time zone) AND ((documenttype_ildct)::text = 'IM'::text) AND ((costcenter_ilmcu)::text = '1AM'::text) AND ((ordertype_ildcto)::text = 'WO'::text))
                          ->  Index Scan using f4111_9999_idx5 on f4111_9999 v_1  (cost=0.14..8.16 rows=1 width=40)
                                Index Cond: (((documenttype_ildct)::text = 'IM'::text) AND ((ordertype_ildcto)::text = 'WO'::text))
                                Filter: ((datetransactionjulian_iltrdj >= '2011-01-01 00:00:00'::timestamp without time zone) AND ((costcenter_ilmcu)::text = '1AM'::text))
                          ->  Index Scan using f4111_2017_idx5 on f4111_2017 v_2  (cost=0.14..8.16 rows=1 width=40)
                                Index Cond: (((documenttype_ildct)::text = 'IM'::text) AND ((ordertype_ildcto)::text = 'WO'::text))
                                Filter: ((datetransactionjulian_iltrdj >= '2011-01-01 00:00:00'::timestamp without time zone) AND ((costcenter_ilmcu)::text = '1AM'::text))
                          ->  Bitmap Heap Scan on f4111_2016 v_3  (cost=511.81..13612.41 rows=9453 width=12)
                                Recheck Cond: (((documenttype_ildct)::text = 'IM'::text) AND ((ordertype_ildcto)::text = 'WO'::text))
                                Filter: ((datetransactionjulian_iltrdj >= '2011-01-01 00:00:00'::timestamp without time zone) AND ((costcenter_ilmcu)::text = '1AM'::text))
                                ->  Bitmap Index Scan on f4111_2016_idx5  (cost=0.00..509.44 rows=20502 width=0)
                                      Index Cond: (((documenttype_ildct)::text = 'IM'::text) AND ((ordertype_ildcto)::text = 'WO'::text))
                          ->  Bitmap Heap Scan on f4111_2015 v_4  (cost=13279.30..378625.74 rows=277646 width=13)
                                Recheck Cond: (((documenttype_ildct)::text = 'IM'::text) AND ((ordertype_ildcto)::text = 'WO'::text))
                                Filter: ((datetransactionjulian_iltrdj >= '2011-01-01 00:00:00'::timestamp without time zone) AND ((costcenter_ilmcu)::text = '1AM'::text))
                                ->  Bitmap Index Scan on f4111_2015_idx5  (cost=0.00..13209.89 rows=576546 width=0)
                                      Index Cond: (((documenttype_ildct)::text = 'IM'::text) AND ((ordertype_ildcto)::text = 'WO'::text))
                          ->  Bitmap Heap Scan on f4111_2014 v_5  (cost=14262.66..400904.20 rows=286705 width=13)
                                Recheck Cond: (((documenttype_ildct)::text = 'IM'::text) AND ((ordertype_ildcto)::text = 'WO'::text))
                                Filter: ((datetransactionjulian_iltrdj >= '2011-01-01 00:00:00'::timestamp without time zone) AND ((costcenter_ilmcu)::text = '1AM'::text))
                                ->  Bitmap Index Scan on f4111_2014_idx5  (cost=0.00..14190.98 rows=619055 width=0)
                                      Index Cond: (((documenttype_ildct)::text = 'IM'::text) AND ((ordertype_ildcto)::text = 'WO'::text))
                          ->  Bitmap Heap Scan on f4111_2013 v_6  (cost=13026.39..430799.00 rows=233531 width=13)
                                Recheck Cond: (((documenttype_ildct)::text = 'IM'::text) AND ((ordertype_ildcto)::text = 'WO'::text))
                                Filter: ((datetransactionjulian_iltrdj >= '2011-01-01 00:00:00'::timestamp without time zone) AND ((costcenter_ilmcu)::text = '1AM'::text))
                                ->  Bitmap Index Scan on f4111_2013_idx5  (cost=0.00..12968.00 rows=567557 width=0)
                                      Index Cond: (((documenttype_ildct)::text = 'IM'::text) AND ((ordertype_ildcto)::text = 'WO'::text))
                          ->  Bitmap Heap Scan on f4111_2012 v_7  (cost=12008.94..348884.89 rows=256980 width=13)
                                Recheck Cond: (((documenttype_ildct)::text = 'IM'::text) AND ((ordertype_ildcto)::text = 'WO'::text))
                                Filter: ((datetransactionjulian_iltrdj >= '2011-01-01 00:00:00'::timestamp without time zone) AND ((costcenter_ilmcu)::text = '1AM'::text))
                                ->  Bitmap Index Scan on f4111_2012_idx5  (cost=0.00..11944.69 rows=520026 width=0)
                                      Index Cond: (((documenttype_ildct)::text = 'IM'::text) AND ((ordertype_ildcto)::text = 'WO'::text))
                          ->  Bitmap Heap Scan on f4111_2011 v_8  (cost=15274.23..329410.87 rows=345915 width=13)
                                Recheck Cond: (((documenttype_ildct)::text = 'IM'::text) AND ((ordertype_ildcto)::text = 'WO'::text))
                                Filter: ((datetransactionjulian_iltrdj >= '2011-01-01 00:00:00'::timestamp without time zone) AND ((costcenter_ilmcu)::text = '1AM'::text))
                                ->  Bitmap Index Scan on f4111_2011_idx5  (cost=0.00..15187.75 rows=660732 width=0)
                                      Index Cond: (((documenttype_ildct)::text = 'IM'::text) AND ((ordertype_ildcto)::text = 'WO'::text))

0 个答案:

没有答案