Oracle
 sql >> база данни >  >> RDS >> Oracle

Кога Oracle индексира стойности на нулеви колони?

Ако някоя индексирана колона съдържа стойност, различна от нула, този ред ще бъде индексиран. Както можете да видите в следващия пример, само един ред не се индексира и това е редът, който има NULL и в двете индексирани колони. Можете също да видите, че Oracle определено индексира ред, когато водещата колона на индекса има стойност NULL.

SQL> create table big_table as
  2       select object_id as pk_col
  3               , object_name as col_1
  4               , object_name as col_2
  5  from all_objects
  6  /

Table created.

SQL> select count(*) from big_table
  2  /

  COUNT(*)
----------
     69238

SQL> insert into big_table values (9999990, null, null)
  2  /

1 row created.

SQL> insert into big_table values (9999991, 'NEW COL 1', null)
  2  /

1 row created.

SQL> insert into big_table values (9999992, null, 'NEW COL 2')
  2  /

1 row created.

SQL> select count(*) from big_table
  2  /

  COUNT(*)
----------
     69241

SQL> create index big_i on big_table(col_1, col_2)
  2  /

Index created.

SQL> exec dbms_stats.gather_table_stats(user, 'BIG_TABLE', cascade=>TRUE)

PL/SQL procedure successfully completed.


SQL> select num_rows from user_indexes where index_name = 'BIG_I'
  2  /

  NUM_ROWS
----------
     69240

SQL> set autotrace traceonly exp
SQL>
SQL> select pk_col from big_table
  2  where col_1 = 'NEW COL 1'
  3  /

Execution Plan
----------------------------------------------------------
Plan hash value: 1387873879

-----------------------------------------------------------------------------------------
| Id  | Operation                   | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |           |     2 |    60 |     4   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| BIG_TABLE |     2 |    60 |     4   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | BIG_I     |     2 |       |     3   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------

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

   2 - access("COL_1"='NEW COL 1')

SQL> select pk_col from big_table
  2  where col_2 = 'NEW COL 2'
  3  /

Execution Plan
----------------------------------------------------------
Plan hash value: 3993303771

-------------------------------------------------------------------------------
| Id  | Operation         | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |           |     2 |    60 |   176   (1)| 00:00:03 |
|*  1 |  TABLE ACCESS FULL| BIG_TABLE |     2 |    60 |   176   (1)| 00:00:03 |
-------------------------------------------------------------------------------

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

   1 - filter("COL_2"='NEW COL 2')

SQL> select pk_col from big_table
  2  where col_1 is null
  3  and col_2 = 'NEW COL 2'
  4  /

Execution Plan
----------------------------------------------------------
Plan hash value: 1387873879

-----------------------------------------------------------------------------------------
| Id  | Operation                   | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |           |     1 |    53 |     4   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| BIG_TABLE |     1 |    53 |     4   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | BIG_I     |     2 |       |     3   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------

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

   2 - access("COL_1" IS NULL AND "COL_2"='NEW COL 2')
       filter("COL_2"='NEW COL 2')

SQL> select pk_col from big_table
  2  where col_1 is null
  3  and col_2 is null
  4  /

Execution Plan
----------------------------------------------------------
Plan hash value: 3993303771

-------------------------------------------------------------------------------
| Id  | Operation         | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |           |     1 |    53 |   176   (1)| 00:00:03 |
|*  1 |  TABLE ACCESS FULL| BIG_TABLE |     1 |    53 |   176   (1)| 00:00:03 |
-------------------------------------------------------------------------------

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

   1 - filter("COL_1" IS NULL AND "COL_2" IS NULL)

SQL>

Този пример работи на Oracle 11.1.0.6. Но съм доста убеден, че важи за всички версии.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да премахнете нулата, когато цялата част е нула в Oracle

  2. ORA-12170:TNS:Възникна изчакване на връзката

  3. Достъп до таблицата на друг потребител в рамките на съхранена процедура на Oracle

  4. Как да ускорите зареждането на данни от oracle sql в pandas df

  5. Как да разберете кога таблицата на Oracle е актуализирана за последен път