oracle培训第二天

xiaoxiao2021-02-28  102

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'); insert into L values(2,'b'); insert into L values(2,'c'); insert into L values(4,'d'); insert into U values(1,'A'); insert into U values(2,'B'); insert into U 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); select * from l natural join u update l set a='A' where id =1; update u set a='A' where id =1; select * from l natural join u 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 union select * from emp union all select * from emp1 union all select * from emp intersect select * from emp1 intersect select * from emp minus select * from emp1 minus select * from emp select id,name1 from l union all select empno,ename from emp select id,name1 from l order by name1 union all select empno,ename from emp order by ename select id,name1 from l  union all select empno,ename from emp order by ename select id,name1 from l  union all 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语句 drop table emp1; 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 select * from emp1; update emp1 set loc =(select loc from dept where deptno = emp1.deptno) select * from emp1; update emp1 set loc = null; update emp1 set deptno =99 ,loc ='aaaa' where empno =7788; select * from emp1; update emp1 set loc =(select loc from dept where deptno = emp1.deptno) where exists(select 1 from dept where deptno = emp1.deptno) select * from emp1; 关联子查询特殊形式 exists和not exists 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') 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),唯一索引指键值不重复 drop table emp1; create table emp1 as select * from emp; 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'; create unique index emp1_empno_index on emp1(empno); update emp1 set empno = 7788 where empno =7900 或者 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 优化器使用索引的扫描方式 drop table emp1; create table emp1 as select * from emp; 索引唯一扫描。通过唯一索引查找一个数值返回单个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)在唯一组合索引上,对组合索引使用部分列进行查询(含引导列),导致查询出多行 select * from emp1 where deptno =20; 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; select empno  from emp1; 索引快速扫描 扫描索引中的所有数据块 drop table emp1; create table emp1 as select * from emp; 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; analyze index index_t_id validate structure; select name,height,pct_used,del_lf_rows/lf_rows from index_stats 当下列三种情形之一发生时,说明积累的碎片应该整理了 1.height >=4 2.pct_used < 50% 3 delete_lf_rows/lf_rows >0.2 alter index index_t_id rebuild;//重建 analyze index index_t_id validate structure; 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
转载请注明原文地址: https://www.6miu.com/read-55215.html

最新回复(0)