sql >> Databáze >  >> RDS >> Oracle

Oracle - Použití indexu s volitelnými parametry

NVL trik by měl fungovat a umožnit přístup k indexu. Ve skutečnosti NVL je obecně nejlepší způsob, jak toho dosáhnout, a obvykle funguje lépe než jiné podmínky zahrnující CASE nebo OR . Použil jsem NVL trik mnohokrát a jednoduchý testovací případ níže ukazuje, že může používat index.

Schéma

create table xx_people(id_number number, a number, b number);

insert into xx_people
select level, level, level from dual connect by level <= 100000;

commit;

begin
    dbms_stats.gather_table_stats(user, 'xx_people');
end;
/

create index xx_people_idx1 on xx_people(id_number, -1);

Vygenerovat plán provádění

explain plan for
select *
from xx_people
where id_number = nvl(:p_id_number, id_number);

select * from table(dbms_xplan.display);

Prováděcí plán

Plan hash value: 3301250992

----------------------------------------------------------------------------------------------------------
| Id  | Operation                              | Name            | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                       |                 |   100K|  3808K|   106   (1)| 00:00:01 |
|   1 |  VIEW                                  | VW_ORE_67373E14 |   100K|  3808K|   106   (1)| 00:00:01 |
|   2 |   UNION-ALL                            |                 |       |       |            |          |
|*  3 |    FILTER                              |                 |       |       |            |          |
|   4 |     TABLE ACCESS BY INDEX ROWID BATCHED| XX_PEOPLE       |     1 |    15 |     3   (0)| 00:00:01 |
|*  5 |      INDEX RANGE SCAN                  | XX_PEOPLE_IDX1  |     1 |       |     2   (0)| 00:00:01 |
|*  6 |    FILTER                              |                 |       |       |            |          |
|*  7 |     TABLE ACCESS FULL                  | XX_PEOPLE       |   100K|  1464K|   103   (1)| 00:00:01 |
----------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   3 - filter(:P_ID_NUMBER IS NOT NULL)
   5 - access("ID_NUMBER"=:P_ID_NUMBER)
   6 - filter(:P_ID_NUMBER IS NULL)
   7 - filter("ID_NUMBER" IS NOT NULL)

Ten plán je zpočátku trochu matoucí. Ale má to nejlepší z obou světů; operace filtrování umožňuje společnosti Oracle rozhodnout se za běhu o použití úplného prohledávání tabulky, když je proměnná vazby null (a jsou vráceny všechny řádky), a indexu, když proměnná vazby není null (a je vráceno pouze několik řádků).

To vše znamená, že ve vašem konkrétním případě se pravděpodobně děje něco divného. Možná budete muset odeslat plně reprodukovatelný testovací případ, abychom zjistili, proč se index nepoužívá.




  1. Dotaz MySQL pro vrácení řádků, které obsahují mezery

  2. Jak používat spojení na třech stolech

  3. Při instalaci pg (0.18.2) došlo k chybě a Bundler nemůže pokračovat

  4. Jak monitorovat stav instancí databáze