Index is ignored on joined view in Postgres

牧云@^-^@ 提交于 2019-12-24 02:08:14

问题


I have a table in my DB (Postgres 9.3.4) with index on couple of columns. Also I have a view based only on this table with grouping and filter by indexed columns.

    CREATE OR REPLACE VIEW vstatement_base AS                               
     SELECT o.bitrnrequestid AS bitrnreqid,                                 
        o.icardid,                                                          
        o.icardaccountid,                                                   
        o.iterminalid,                                                      
        abs(sum(                                                            
            CASE                                                            
                WHEN o.sitypeex = ANY (ARRAY[1, 11]) THEN o.namount         
                ELSE 0::numeric                                             
            END)) AS charged,                                               
        abs(sum(                                                            
            CASE                                                            
                WHEN o.sitypeex = ANY (ARRAY[2, 12]) THEN o.namount         
                ELSE 0::numeric                                             
            END)) AS withdrawn                                              
       FROM ttrnoperations o                                                
      WHERE o.sicommitstate >= 1 AND o.bcancelled = false                   
      GROUP BY o.bitrnrequestid, o.icardid, o.icardaccountid, o.iterminalid;

When I select some data from this view - I get an index scan in execution plan - all as wanted.

   query: 
   select * from ls.vstatement_base limit 100  

   execution plan:
   "Limit  (cost=0.42..200.73 rows=100 width=276) (actual time=0.088..1.614 rows=100 loops=1)"
   "  ->  GroupAggregate  (cost=0.42..806065.36 rows=404438 width=33) (actual time=0.086..1.601 rows=100 loops=1)"
   "        ->  Index Scan using ix_ttrnoperations_vstmt_base_id on ttrnoperations o  (cost=0.42..751384.32 rows=850958 width=33) (actual time=0.027..0.393 rows=239 loops=1)"
   "              Filter: ((NOT bcancelled) AND (sicommitstate >= 1))"
   "Total runtime: 1.749 ms"

But when I join this view with any other table I get an sequence scan... so index is ignored for some reason.

    query:
    select * from ls.vstatement_base v, ttrnrequests tr WHERE v.bitrnreqid=tr.biid  limit 100  

   execution plan:
   "Limit  (cost=157369.84..157396.40 rows=100 width=368) (actual time=992.271..992.802 rows=100 loops=1)"
   "  ->  Merge Join  (cost=157369.84..264813.66 rows=404438 width=368) (actual time=992.269..992.790 rows=100 loops=1)"
   "        Merge Cond: (o.bitrnrequestid = tr.biid)"
   "        ->  GroupAggregate  (cost=157369.42..214177.85 rows=404438 width=33) (actual time=992.246..992.692 rows=100 loops=1)"
   "              ->  Sort  (cost=157369.42..159496.81 rows=850958 width=33) (actual time=992.211..992.251 rows=239 loops=1)"
   "                    Sort Key: o.bitrnrequestid, o.icardid, o.icardaccountid, o.iterminalid"
   "                    Sort Method: external merge  Disk: 36520kB"
   "                    ->  Seq Scan on ttrnoperations o  (cost=0.00..27012.46 rows=850958 width=33) (actual time=0.074..292.888 rows=851049 loops=1)"
   "                          Filter: ((NOT bcancelled) AND (sicommitstate >= 1))"
   "                          Rows Removed by Filter: 988"
   "        ->  Index Scan using pk_ttrnrequests_biid on ttrnrequests tr  (cost=0.42..40509.61 rows=410539 width=92) (actual time=0.018..0.044 rows=100 loops=1)"
   "Total runtime: 996.706 ms"

If I set enable_seqscan to 'off' - then instead of sequence scan I get an Bitmap index scan/Bitmap heap scan.

    execution plan:
    "Limit  (cost=175445.88..175472.45 rows=100 width=368) (actual time=114.157..1141.831 rows=100 loops=1)"
    "  ->  Merge Join  (cost=175445.88..282889.70 rows=404438 width=368) (actual time=1141.155..1141.823 rows=100 loops=1)"
    "        Merge Cond: (o.bitrnrequestid = tr.biid)"
    "        ->  GroupAggregate  (cost=175445.46..232253.90 rows=404438 width=33) (actual time=1141.113..1141.640 rows=100 loops=1)"
    "              ->  Sort  (cost=175445.46..177572.86 rows=850958 width=33) (actual time=1141.078..1141.122 rows=239 loops=1)"
    "                    Sort Key: o.bitrnrequestid, o.icardid, o.icardaccountid, o.iterminalid"
    "                    Sort Method: external merge  Disk: 36520kB"
    "                    ->  Bitmap Heap Scan on ttrnoperations o  (cost=18089.53..45088.51 rows=850958 width=33) (actual time=88.872..445.549 rows=851049 loops=1)"
    "                          Recheck Cond: (sicommitstate >= 1)"
    "                          Filter: (NOT bcancelled)"
    "                          Rows Removed by Filter: 363"
    "                          ->  Bitmap Index Scan on ix_ttrnoperations_vstmt_base_state  (cost=0.00..17876.80 rows=850958 width=0) (actual time=87.335..87.335 rows=851049 loops=1)"
    "                                Index Cond: ((sicommitstate >= 1) AND (bcancelled = false))"
    "        ->  Index Scan using pk_ttrnrequests_biid on ttrnrequests tr  (cost=0.42..40509.61 rows=410539 width=92) (actual time=0.039..0.120 rows=100 loops=1)"
    "Total runtime: 1145.811 ms"

But, when I put join inside view (new view vstatement_base1 created) - then I get correct index scan as i first case.

    query:
    select * from ls.vstatement_base1 v limit 100  

   execution plan:
    "Limit  (cost=175.92..695.41 rows=100 width=276) (actual time=0.108..2.412 rows=100 loops=1)"
    "  ->  GroupAggregate  (cost=175.92..2097148.02 rows=404438 width=33) (actual time=0.106..2.389 rows=100 loops=1)"
    "        ->  Merge Join  (cost=175.92..2042466.98 rows=850958 width=33) (actual time=0.051..0.999 rows=239 loops=1)"
    "              Merge Cond: (o.bitrnrequestid = tr.biid)"
    "              ->  Index Scan using ix_ttrnoperations_vstmt_base_id on ttrnoperations o  (cost=0.42..1444271.58 rows=850958 width=33) (actual time=0.018..0.560 rows=239 loops=1)"
    "                    Filter: ((NOT bcancelled) AND (sicommitstate >= 1))"
    "              ->  Materialize  (cost=0.42..584386.07 rows=410539 width=8) (actual time=0.025..0.205 rows=239 loops=1)"
    "                    ->  Index Only Scan using pk_ttrnrequests_biid on ttrnrequests tr  (cost=0.42..583359.73 rows=410539 width=8) (actual time=0.018..0.120 rows=101 loops=1)"
    "                          Heap Fetches: 101"
    "Total runtime: 2.615 ms"

So... can anybody tell me - why postgres ignores index when I put "join" outside view?

Thank You.

来源:https://stackoverflow.com/questions/27142333/index-is-ignored-on-joined-view-in-postgres

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!