Oracle. Select all if parameter is null else return specific item issue

后端 未结 3 1061
自闭症患者
自闭症患者 2021-01-26 05:43

I need to return all records if input parameter is null.

I\'ve written a simple query

declare  
   l_sql varchar2(100);
   i number := 1;
 begin
   l_sq         


        
3条回答
  •  北荒
    北荒 (楼主)
    2021-01-26 06:27

    IS NULL suppresses the index usage. Because NULL values are not indexed.

    There are two ways to make the use of index with IS NULL :

    1.BITMAP index. However, more applicable in OLTP systems.

    2.My favourite way, and nice to demonstrate. We could make the leaves of the b-tree index a constant. Thus, making use of index while querying for NULL. Basically, the NULLs are all together, at the top/bottom of the index. Oracle can use the index forwards or backwards, so doesn't really matter. And it does a full scan of the index.

    I have answered a similar question here http://www.orafaq.com/forum/mv/msg/194746/625371/#msg_625371

    The first scenario won't use the index due to the OR is null condition :

    SQL> SELECT * FROM PROD_NEW;
    
    PROFILE_TYPE
    ---------------
    
    Prod
    Prodparallel
    
    Prod
    
    SQL> CREATE INDEX PROD_NEW_I1 ON PROD_NEW
      2    (PROFILE_TYPE
      3    );
    
    Index created.
    
    SQL> EXPLAIN PLAN FOR SELECT * FROM PROD_NEW WHERE PROFILE_TYPE = 'Prod' OR PROFILE_TYPE IS NULL;
    
    Explained.
    
    SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
    
    PLAN_TABLE_OUTPUT
    --------------------------------------------------------------------------------
    Plan hash value: 2121244107
    
    ------------------------------------------------------------------------------
    | Id  | Operation         | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
    ------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT  |          |     3 |    15 |     3   (0)| 00:00:01 |
    |*  1 |  TABLE ACCESS FULL| PROD_NEW |     3 |    15 |     3   (0)| 00:00:01 |
    ------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
    PLAN_TABLE_OUTPUT
    --------------------------------------------------------------------------------
    
       1 - filter("PROFILE_TYPE" IS NULL OR "PROFILE_TYPE"='Prod')
    
    13 rows selected
    

    Let's make the leaves constant :

    SQL> DROP INDEX PROD_NEW_I1;
    
    Index dropped.
    
    SQL> CREATE INDEX PROD_NEW_I1 ON PROD_NEW
      2    (PROFILE_TYPE,1
      3    );
    
    Index created.
    
    SQL> EXPLAIN PLAN FOR SELECT * FROM PROD_NEW WHERE PROFILE_TYPE = 'Prod' OR PROFILE_TYPE IS NULL;
    
    Explained.
    
    SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
    
    PLAN_TABLE_OUTPUT
    --------------------------------------------------------------------------------
    Plan hash value: 1272076902
    
    --------------------------------------------------------------------------------
    | Id  | Operation        | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
    --------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT |             |     3 |    15 |     1   (0)| 00:00:01 |
    |*  1 |  INDEX FULL SCAN | PROD_NEW_I1 |     3 |    15 |     1   (0)| 00:00:01 |
    --------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
    PLAN_TABLE_OUTPUT
    --------------------------------------------------------------------------------
    
       1 - filter("PROFILE_TYPE" IS NULL OR "PROFILE_TYPE"='Prod')
    
    13 rows selected.
    
    SQL>
    

提交回复
热议问题