Re: Inefficient query plan using large in-list

From: Senthil Subramanian <skumar.sen_at_gmail.com>
Date: Thu, 16 May 2019 13:14:26 -0400
Message-ID: <CAFUEfmFJ8o+rhpg+Fc-gU4jig2RUBdZNT0OrxWAdY608nPEGwA_at_mail.gmail.com>



Hello Jonathan,

Okay, I thought it would be simple to force the optimizer to push the predicate to get the intended plan. It works fine with a GTT!

Oracle version is 12.1.0.2

Yes, the IN list with literals works the way I want it to be as you can see below

SQL_ID 6ayrrb28h57pt, child number 0



select sh.* from secmaster_history sh where sh.security_alias in (927763,927762,927779) and to_date('15-MAY-2010') between effective_date and nvl(expiration_date,sysdate)

Plan hash value: 1878147942


| Id  | Operation                                        | Name
              | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | Pstart|
Pstop | A-Rows | A-Time | Buffers | Reads | OMem | 1Mem | O/1/M |

| 0 | SELECT STATEMENT |
             |      3 |        |       |   148 (100)|          |       |
   |      9 |00:00:00.08 |    1179 |    346 |       |       |          |
|*  1 |  VIEW                                            |
SECMASTER_HISTORY             |      3 |    142 |   619K|   148   (1)|
00:00:01 |       |       |      9 |00:00:00.08 |    1179 |    346 |
 |       |          |

| 2 | WINDOW SORT |
| 3 | 142 | 221K| 148 (1)| 00:00:01 | | | 1140 |00:00:00.08 | 1179 | 346 | 832K| 511K| 3/0/0|
| 3 | INLIST ITERATOR |
| 3 | | | | | | | 1140 |00:00:00.05 | 1179 | 346 | | | |
| 4 | MAT_VIEW ACCESS BY GLOBAL INDEX ROWID BATCHED|
SECMASTER_HISTORY_MV | 9 | 142 | 221K| 147 (0)| 00:00:01 | ROWID | ROWID | 1140 |00:00:00.05 | 1179 | 346 | | | | |* 5 | INDEX RANGE SCAN | SYS_C_SNAP$_228PK_SECDBO_SECM | 9 | 142 | | 6 (0)| 00:00:01 | | | 1140 |00:00:00.01 | 39 | 5 | | | | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):


   1 - filter(("EFFECTIVE_DATE"<=TO_DATE('15-MAY-2010') AND NVL("EXPIRATION_DATE",SYSDATE_at_!)>=TO_DATE('15-MAY-2010')))

   5 - access((("SECURITY_ALIAS"=927762 OR "SECURITY_ALIAS"=927763 OR "SECURITY_ALIAS"=927779)) AND "SRC_INTFC_INST"=4) On Thu, May 16, 2019 at 12:23 PM Jonathan Lewis <jonathan_at_jlcomp.demon.co.uk> wrote:

>
> As others have noted, table() functions don't mix well with the optimizer
> and various transformation may fail to appear for reasons that are not
> obvious to mere mortals such as us.
>
> Which version of Oracle, though, and have you demonstrated that a query
> like the following behaves the way you want because sometimes the presence
> of analytic functions blocks the query transformation you expect to see:
>
> select
>   {columns}
> from secmaster_history
> where
> where  security_alias in (1,2,3,4,5)
> and    to_date('15-MAY-2010') between effective_date and
> nvl(expiration_date,sysdate)
>
>
> Regards
> Jonathan Lewis
>
> ________________________________________
> From: oracle-l-bounce_at_freelists.org <oracle-l-bounce_at_freelists.org> on
> behalf of Senthil Subramanian <skumar.sen_at_gmail.com>
> Sent: 16 May 2019 16:43
> To: oracle-l_at_freelists.org
> Subject: Inefficient query plan using large in-list
>
> Hello list members,
>
> I would like get some help to solve a performance issue.  I have a query
> with a simple view which needs to return rows when application passes comma
> separated input values.  The view goes against an MVIEW with an analytic
> (LAG) function to compute the expiration date using an effective date for a
> given security ID & src.  Below is the view definition:
>
>
> CREATE OR REPLACE FORCE VIEW SECMASTER_HISTORY
>
> AS
>
> SELECT security_alias,
>
>        src_intfc_inst,
>
>        effective_date,
>
>        (effective_date) over (partition by security_alias,src_intfc_inst
> order by effective_date desc) - interval '1' second expiration_date,
>
>        <other cols>
>
> FROM   SECMASTER_HISTORY_MV
>
> WHERE  src_intfc_inst = 4;
>
>
> There is an unique index on the MV with columns
> (SECURITY_ALIAS,SRC_INTFC_INST,EFFECTIVE_DATE)
>
>
> When I run the below query
>
>
> select sh.*
>
> from   table(cast(multiset(select level from dual
>
>                            connect by level <= length
> (regexp_replace(:in_list, '[^,]+')) + 1) as sys.OdciNumberList)) xt,
>
>        secmaster_history sh
>
> where  sh.security_alias = xt.column_value
>
> and    to_date('15-MAY-2010') between effective_date and
> nvl(expiration_date,sysdate) ;
>
>
> The optimizer is not pushing the predicate into the view and does a full
> scan on the MV causing performance issue!
>
>
>
> --------------------------------------------------------------------------------------------------------------------------------------------
>
> | Id  | Operation                            | Name                 |
> Rows  | Bytes |TempSpc| Cost (%CPU)| Time     | Pstart| Pstop |IN-OUT|
>
>
> --------------------------------------------------------------------------------------------------------------------------------------------
>
> |   0 | SELECT STATEMENT                     |                      |
>  387K|  1653M|       |    17M  (1)| 00:11:12 |      |        |      |
>
> |   1 |  MERGE JOIN                          |                      |
>  387K|  1653M|       |    17M  (1)| 00:11:12 |      |        |      |
>
> |*  2 |   VIEW                               | SECMASTER_HISTORY    |
> 47M|   199G|       |    17M  (1)| 00:11:12 |      |        |      |
>
> |   3 |    WINDOW SORT                       |                      |
> 47M|    71G|    91G|    17M  (1)| 00:11:12 |      |        |      |
>
> |   4 |     PARTITION RANGE ALL              |                      |
> 47M|    71G|       |  1209K  (1)| 00:00:48 |    1 |1048575|       |
>
> |*  5 |      MAT_VIEW ACCESS FULL            | SECMASTER_HISTORY_MV |
> 47M|    71G|       |  1209K  (1)| 00:00:48 |    1 |1048575|       |
>
> |*  6 |   SORT JOIN                          |                      |
> 8168 | 16336 |       |    30   (4)| 00:00:01 |      |        |      |
>
> |   7 |    COLLECTION ITERATOR SUBQUERY FETCH|                      |
> 8168 | 16336 |       |    29   (0)| 00:00:01 |      |        |      |
>
> |*  8 |     CONNECT BY WITHOUT FILTERING     |                      |
>  |       |       |            |          |      |        | PCWP |
>
> |   9 |      FAST DUAL                       |                      |
>  1 |       |       |     2   (0)| 00:00:01 |      |        | PCWP |
>
>
> --------------------------------------------------------------------------------------------------------------------------------------------
>
>
> Predicate Information (identified by operation id):
>
> ---------------------------------------------------
>
>
>    2 - filter("EFFECTIVE_DATE"<=TO_DATE('15-MAY-2010') AND
> NVL("EXPIRATION_DATE",SYSDATE_at_!)>=TO_DATE('15-MAY-2010'))
>
>    5 - filter("SRC_INTFC_INST"=4)
>
>    6 - access("SH"."SECURITY_ALIAS"=VALUE(KOKBF$))
>
>        filter("SH"."SECURITY_ALIAS"=VALUE(KOKBF$))
>
>    8 - filter(LEVEL<=LENGTH( REGEXP_REPLACE (:IN_LIST,'[^,]+'))+1)
>
>
> 25 rows selected.
>
>
> I tried to hint the optimizer but nothing works :-(
>
>
> Any help is highly appreciated!
>
>
> Thanks in advance for your help!
>
>
> Senthil
> --
> http://www.freelists.org/webpage/oracle-l
>
>
>

--
http://www.freelists.org/webpage/oracle-l
Received on Thu May 16 2019 - 19:14:26 CEST

Original text of this message