列值有NULL值创建索引

如果where条件列查询目标SQL返回数据量比较少时,可以使用创建索引的方式来减少全表扫描的消耗。
例子:以ta表为例,在object_id上创建单键值B-Tree索引:
创建测试表:
create table ta as select * from dba_objects;
创建索引:
create index idx_object_id on ta( object_id) ;
查看执行计划:
select /*+ gather_plan_statistics */
 *
  from ta
 where ta.object_id is null;
 
SQL> select * from table(dbms_xplan.display_cursor(null,0,'ALLSTATS LAST'));

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------------------------------
SQL_ID  88gbh334ujqz7, child number 0
-------------------------------------
select /*+ gather_plan_statistics */  *   from ta  where ta.object_id
is null

Plan hash value: 824468716

---------------------------------------------------------------------------------------------
| Id  | Operation         | Name | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads  |
---------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |      1 |        |      8 |00:00:00.12 |    1100 |   1096 |
|*  1 |  TABLE ACCESS FULL| TA   |      1 |     12 |      8 |00:00:00.12 |    1100 |   1096 |
---------------------------------------------------------------------------------------------

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

   1 - filter("TA"."OBJECT_ID" IS NULL)

Note
-----
   - dynamic sampling used for this statement (level=2)


已选择23行。
通过查看执行计划,执行该语句是走全表扫描,并没有走idx_object_id这个单键值索引,之所以没有走这个索引是因为object_id这一列是有
NULL值的,这时候的逻辑读是1100,物理读是1096.
如果创建一个组合索引的话,那么这个索引是可以包含空值的,创建一个索引以object_id为先导列,第二列使用常数。
drop index idx_object_id;
create index idx_object_id on ta( object_id,1) ;

执行测试语句并查看执行计划:
SQL> select * from table(dbms_xplan.display_cursor(null,0,'ALLSTATS LAST'));

PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------------------------------------------------
SQL_ID  88gbh334ujqz7, child number 0
-------------------------------------
select /*+ gather_plan_statistics */  *   from ta  where ta.object_id
is null

Plan hash value: 1309383053

----------------------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name          | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads  |
----------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |               |      1 |        |      8 |00:00:00.02 |       5 |      2 |
|   1 |  TABLE ACCESS BY INDEX ROWID| TA            |      1 |     12 |      8 |00:00:00.02 |       5 |      2 |
|*  2 |   INDEX RANGE SCAN          | IDX_OBJECT_ID |      1 |   4074 |      8 |00:00:00.01 |       3 |      1 |
----------------------------------------------------------------------------------------------------------------

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

   2 - access("TA"."OBJECT_ID" IS NULL)

Note
-----
   - dynamic sampling used for this statement (level=2)


 通过查看执行计划,现在该sql查询时是通过索引进行查询,并且逻辑读降到了3,物理读降到1

你可能感兴趣的:(SQL,Tuning)