当前位置:Gxlcms > 数据库问题 > SQL中的null

SQL中的null

时间:2021-07-01 10:21:17 帮助过:2人阅读

  for i in 1..9999 loop

    insert into n1 values(i,‘name‘||i);

    if mod(i,100)=0then

      commit;

    end if;

  end loop;

  insert into n1(sid)values(10000);

  commit;

end;

查询sname列值走的是索引范围扫描

SQL> explain plan for select * from n1 where sname = 'name1';
Explained.

SQL> select * from table(dbms_xplan.display);
Plan hash value: 3644017351
--------------------------------------------------------------------------------
| Id  | Operation	 | Name 	| Rows	| Bytes | Cost (%CPU)| Time
|
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |		|     1 |    75 |     2   (0)| 00:00:01
|
|*  1 |  INDEX RANGE SCAN| N1_SNAME_IND |     1 |    75 |     2   (0)| 00:00:01
|
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - access("SNAME"='name1')
Note
-----
   - dynamic sampling used for this statement (level=2)


is null方式查询,虽然sname中为null的记录1W行中只有一行,但还是没有走索引,也就是说is null不走索引。

SQL> explain plan for select * from n1 where sname is null;
Explained.

SQL> select * from table(dbms_xplan.display);
Plan hash value: 2416923229
--------------------------------------------------------------------------
| Id  | Operation	  | Name | Rows  | Bytes | Cost (%CPU)| Time	 |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |	 |     1 |    75 |     9   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| N1	 |     1 |    75 |     9   (0)| 00:00:01 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter("SNAME" IS NULL)
Note
-----
   - dynamic sampling used for this statement (level=2)
17 rows selected.


如果实际情况确实需要is null查询走索引呢?可通过创建联合索引的方式来实现。

drop index n1_sname ;

create index n1_sname_ind on n1(sname,sid);

 

SQL> explain plan for select * from n1 where  sid is not null and sname is null ;

SQL> select * from table(dbms_xplan.display);
Plan hash value: 3644017351
-------------------------------------------------------------------------------
| Id  | Operation	 | Name 	| Rows	| Bytes | Cost (%CPU)| Time
|
-------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |		|     1 |    75 |     3   (0)| 00:00:01
|
|*  1 |  INDEX RANGE SCAN| N1_SNAME_IND |     1 |    75 |     3   (0)| 00:00:01
|
-------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - access("SNAME" IS NULL)
       filter("SID" IS NOT NULL)
Note
-----
   - dynamic sampling used for this statement (level=2)

18 rows selected.

可以看到创建联合索引后,SQL查询所耗费的资源明显降低。

需要注意的是我们查询最频繁最经常使用列,比如sname要放在联合索引的第一列;同时要走联合索引,需要where后面的条件出现联合索引包含的所有的字段,这也是为什么加了sid这个字段的原因。




 

版权声明:本文为博主原创文章,未经博主允许不得转载。

SQL中的null

标签:

人气教程排行