发布网友 发布时间:2022-04-08 04:12
共2个回答
懂视网 时间:2022-04-08 08:34
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
标签:
热心网友 时间:2022-04-08 05:42
SQL中Null的中文叫法是“空值”,其意思为"没有值"的值,它的数据类型是未知的,在数据库表里Null不占用物理磁盘空间,因为Null就是空无一物嘛,没有东西自然就没有占用。数据库表实际是二维表,新建表时所有的字段值都是Null(空值),同样添加新纪录时未指定字段值前每个字段值也是Null,每个网格由横向(字段名)和纵向记录行确定,当一个网格没有写入数据前其存储的值就是Null(空值),这是天然属性使然,写入数据后其值就变为非"空值",如果我们再将该网格里的数据值擦除掉它又会变为“空值”。筛选含“空值”的记录可以使用"expr is null",反之可以使用“expr is not” 。