天天看点

oracle培训第二天

1.空值

空值的数据行将对算数表达式返回空值

select ename,sal,comm,sal+comm from emp

select sum(sal),sum(sal+comm) from emp

比较表达式有空值时返回假

select ename,sal,comm from emp where sal >=comm

非空值与空值做||时,null转化为"",合并的数据为varchar2

select ename,sal,comm,sal||comm from emp 

外键值可以为null

空值在where子句里用is null 或 is not null

空值在update或insert时,直接使用null

update emp set comm =null where empno =7788

处理空值的几种函数方法

nvl(expr1,expr2)

select nvl(1,2) from dual;

select nvl(null,2) from dual;

nvl2(expr1,expr2,expr3)

当第一参数不为null时,取第二个参数的值,否则取第三个参数的值

select nvl2(1,2,3) from dual;

select nvl2(null,2,3) from dual;

select ename ,nvl2(comm,sal+comm,sal) from emp;

nullif(expr1,expr2)

当第一个参数和第二个参数一样时返回为空,当两个参数不一样时返回第一个参数,第一个参数不允许为空

select nullif(1,1) from dual

select nullif(1,2) from dual

coalesce(expr1,expr2,...)

返回从左起始,第一个不为空的值,如果所有参数都为空,则返回空值

select coalesce(null,null,1,1) from dual

select coalesce(null,null,null,null) from dual

2.多表连接技术

交叉连接(笛卡尔积)

create table L(id int ,name1 varchar(10));

create table U(id int,name2 varchar(10));

insert into L

values(1,'a');

values(2,'b');

values(2,'c');

values(4,'d');

insert into U

values(1,'A');

values(2,'B');

values(3,'C');

select * from l cross join u--sql99

select * from l,u--oracle

非等值连接

select empno,ename,sal,grade,losal,hisal from emp,salgrade where sal between losal and hisal

等值连接

内连接

select * from l inner join u on l.id = u.id

select * from l, u where l.id = u.id

外连接(左外,右外,全连接)

select * from l left outer join u on l.id = u.id;

select * from l left join u on l.id = u.id;

select * from l,u where l.id = u.id(+);

select * from l right outer  join u on l.id = u.id;

select * from l right   join u on l.id = u.id;

select * from l,u where l.id(+) = u.id;

select * from l full  join u on l.id = u.id;

自连接

select * from l ,l

select * from l a,l  

自然连接(隐含连接条件,自动匹配连接字段)

select * from emp natural join dept

select * from emp  join dept using(deptno)

select * from l natural join u

alter table l add  A varchar(2);

alter table u add  A varchar(2);

update l set a='A' where id =1;

update u set a='A' where id =1;

select * from l  join u using(id)

select * from l  join u using(id,a)

select l.id from l  join u using(id)

select a from l  join u using(id)

集合运算

create table emp1 as select * from emp where rownum =1

insert into emp1

values(3030,'张振磊','CLERK',7788,sysdate,800,null,10)

union

select * from emp1

select * from emp

union all

intersect

minus

select id,name1 from l

select empno,ename from emp

select id,name1 from l order by name1

select empno,ename from emp order by ename

select id,name1 from l 

select empno,ename from emp order by name1

3.子查询

单行单列子查询(>,<,=,<>,>=,<=)

select ename,sal from emp where sal >(select sal from emp where empno =7788)

多行单列子查询(in,not in,all,any)

select ename from emp where empno in(select mgr from emp  )

select ename from emp where empno not in(select mgr from emp  )

select ename from emp where empno not in(select nvl(mgr,0) from emp  )

select ename ,deptno,sal from emp where sal >all(select avg(sal) from emp group by deptno)

select ename ,deptno,sal from emp where sal >any(select avg(sal) from emp group by deptno)

多行多列子查询

drop table emp1;

create table emp1 as select * from emp;

update emp1 set sal=1600,comm=300 where deptno <>30 and empno =7369;

select * from emp1 where (sal,comm) in(select sal,comm from emp1 where deptno =30) and deptno <> 30

4.布尔运算符 not

select * from emp where empno =7788

select * from emp where not empno =7788

select * from emp where empno !=7788

select * from emp where not empno !=7788

select * from emp where ename like 'S%'

select * from emp where ename not like 'S%'

select * from emp where not ename like 'S%'

select * from emp where not ename not like 'S%'

select * from emp where deptno in(10)

select * from emp where deptno not in(10)

select * from emp where not deptno in(10)

select * from emp where not deptno not in(10)

select * from emp where sal between 1500 and 3000

select * from emp where sal not between 1500 and 3000

select * from emp where not sal between 1500 and 3000

select * from emp where not sal not between 1500 and 3000

select * from emp where comm is null

select * from emp where comm is not null

select * from emp where not comm is null

select * from emp where not comm is not null

select * from emp where exists(select * from dept where deptno = emp.deptno and dname ='SALES')

select * from emp where not exists(select * from dept where deptno = emp.deptno and dname ='SALES')

from 子句使用子查询(也叫内联视图)

select ename,sal,avgsal from emp,(select deptno,avg(sal) avgsal from emp group by deptno ) b

where emp.deptno = b.deptno and emp.sal > b.avgsal

关联子查询

select ename,sal from emp outer where outer.sal > (select  avg(sal) avgsal from emp inner where outer.deptno = inner.deptno )

关联子查询用于update语句

create table emp1 as select emp.*,loc from emp,dept where emp.deptno = dept.deptno(+);

select * from emp1;

update emp1 set loc = null;

update emp1 set deptno =99 ,loc ='aaaa' where empno =7788

update emp1 set loc =(select loc from dept where deptno = emp1.deptno)

update emp1 set deptno =99 ,loc ='aaaa' where empno =7788;

where exists(select 1 from dept where deptno = emp1.deptno)

关联子查询特殊形式 exists和not exists

5.别名

表别名和列别名

select ename 姓名 from emp 员工

select ename 姓 名 from emp 员工

select ename "姓 名" from emp 员工

select * from emp where rownum >1

select * from (select ename,rownum rm from emp )  where rm >1

6.索引

B树索引 根节点块,分支节点块,叶子节点块(rowid,键值)

位图索引(离散度低,男女 1,2)

索引是与表相关的一个可选结构,在逻辑上和物理上都独立于表的数据,索引能优化查询,不能优化DML操作。oracle自动维护索引,频繁的DML操作反而会引起大量的索引维护

常用的B树索引类型

唯一或非唯一索引(unique or  nounique),唯一索引指键值不重复

update emp1 set empno = 7788 where empno =7900

create unique index emp1_empno_index on emp1(empno);

update emp1 set empno =7900 where empno =7788 and ename <>'SCOTT';

或者

drop index emp1_empno_index;

create index emp1_empno_index on emp1(empno);

组合索引(composite)绑定了两个以上列的索引

create index emp1_comp_index on emp1(job,deptno)

反向键索引(reverse)将字节倒置后组建键值,当使用序列产生主键索引时,可以防止叶节点出现热快现象

create index emp1_mgr_index on emp1(mgr) reverse

函数索引,以索引列值的函数值去组织索引

create index emp1_fun_index on emp1(lower(ename)) 

select * from emp1 where lower(ename)='scott';

压缩,重复键值只存储一次,重复的键值在页块中只存储一次,后面跟所有与之匹配的rowid字符串

create index emp1_sal_index on emp1(sal)  compress

升序或降序,叶节点中的键值排序默认是升序的

create index emp1_deptjob_index on emp1(deptno desc,job asc)

select * from user_indexes

select * from user_ind_columns

优化器使用索引的扫描方式

索引唯一扫描。通过唯一索引查找一个数值返回单个rowid。对于唯一组合索引,要在where的谓词“=”后包含所有列的“布尔与”

create unique index index_emp1_empno on emp1(empno);

select * from emp1 where empno =7788;

create index index_emp1_deptnoename on emp1(deptno,ename);

select * from emp1 where deptno =20 and ename ='SCOTT';

select * from emp1 where ename ='SCOTT' and deptno =10;

select * from emp1 where ename ='SCOTT';

select * from emp1 where deptno =20;

索引范围扫描。在非唯一索引上可能返回多行数据。所以在非唯一索引上都使用索引范围扫描。

a)在唯一索引列上使用了range操作符(>,<,>=,<=,between)

select * from emp1 where empno >7788;

select * from emp1 where empno <>7788;

b)在唯一组合索引上,对组合索引使用部分列进行查询(含引导列),导致查询出多行

c)对非唯一索引列上进行的任何查询。不含 布尔或

create index index_emp1_sal on emp1(sal);

select * from emp1 where sal =800;

索引全扫描

对整个index进行扫描,并且顺序的读取其中的数据

select empno  from emp1;

alter table emp1 modify empno not null;

索引快速扫描

扫描索引中的所有数据块

create index index_emp1_empno on emp1(empno);

insert into emp1 select * from emp1;

select empno from emp1;

show parameter multi;

索引的碎片问题

聚簇因子:堆表的表行物理的存储在数据块是无序的,这与插入一行记录首选空闲快的策略有关。而索引的键值又是有序的。当这两者差异越大,聚簇因子的值就越高。

由于对基表做dml操作,便导致对索引表块的自动更改操作,尤其是基表的delete操作会引起index的逻辑删除。只有当index块中的所有index entry都被删除了,这个块才能够被回收,

如果update基表索引列,则索引块会发生entry delete,再entry insert,这些动作都可能产生索引碎片。

create table t (id int);

create index index_t_id on t(id);

begin

  for i in 1..1000000 loop

      insert into t values(i);

      if mod(i,100) = 0 then

         commit;

       end if;

  end loop;

end;

analyze index index_t_id validate structure;

select name,height,pct_used,del_lf_rows/lf_rows from index_stats

delete from t where id < 700000;

当下列三种情形之一发生时,说明积累的碎片应该整理了

1.height >=4

2.pct_used < 50%

3 delete_lf_rows/lf_rows >0.2

alter index index_t_id rebuild;//重建

select name,height,pct_used,del_lf_rows/lf_rows from index_stats;

alter index index_t_id coalesce//比rebuild动作轻 ,融合

索引不可见(invisible)

alter index index_t_id invisible;//优化器不可见,索引正常更新

select * from user_indexes//visibility是invisible

alter index index_t_id unusable;

select * from user_indexes //status是unusable