[Oracle] 《Oracle查询优化改写技巧与案例2.0》读书笔记

前言

只是记录和整理了一些对我有用的笔记,详细得请看原著。

单表查询

查找空值

select * from emp where comm is null

NULL 不支持 加、减、乘、除、大小比较、相等比较,否则只能为空;

处理空值NVL

NVL 只能处理多个参数,如果要处理多个参数,则可以使用COALESCE

在 WHERE 子句中 引用取别名的列

select * from (select sal as 工资, comm as 提成 from emp) x where 工资  <= 1000;

限制返回的行数

rownum 是依次对数据做标识的,需要先有第一名,后面才会有第二名。

select * 
from (select rownum as sn,emp.* from emp where rownum <= 2)
where sn = 2

给查询结果排序

以指定的次序返回查询结果

除了 order by 字段名 ASC 这种写法,还可以写成 order by 3 ASC 意思是按第三列排序。
用数据代替列位置只能用于order by 字句中,其他地方都不能用。

从表中随机返回n条记录

先随机排序,再取数据

select empno, ename
from (select empno,ename from emp order by dbms_random.value())
where rownum <=3

TRANSLATE

select  TRANSLATE ('ab 你好 bcadefg','abcdefg','1234567' ) as new_str from dual;

结果:
12你好2314567

处理排序空值

Oracle 默认 升序时空值在后,降序时空值在前
可以使用关键字 NULLS FIRSTNULLS LAST 更改空值顺序

根据条件取不同列中的值来排序

例如:领导对工资在1000到2000元之前员工排在前面,以便优先查看。

select empno as 编码,
       ename as 姓名,
       sal as 工资
       from emp
       where dempno = 30 
       order by case when sal >= 1000 and sal < 2000 THEN 1 else 2 end,3;

操作多个表

IN、EXISTS和INNER JOIN

IN 写法

select empno, ename, job,sal,deptno
from emp
where (ename,job,sal) in (select ename,job,sal from emp2); 

EXISTS 写法

select empno,ename,job,sal,deptno
from emp a
where exists (select NULL emp2 b where 
                  b.ename = a.ename 
                  and b.job =a.job
                  and b.sal = a.sal )

INNER JOIN 写法

select a.empno,a.ename,a.job,a.sal,a.deptno from emp a 
inner join emp2 b on (b.ename = a.ename and b.job = a.job and b.sal = a.sal) 

JOIN 写法中利用了 HASH JOIN(哈希连接) ,其他两种应用都是HASH JOIN SEMI (哈希半连接)。
更详细的两者的区别请看Oracle 连接和半连接,我是没看懂。。。

插入、更新与删除

阻止对某几列插入

建表的时候会遇到默认值 SYSDATE,这种列一般是为了记录数据生成的时间,不允许手动录入,那么系统控制不到位,可能会出现手动录入的情况发生这时可以通过视图来完成。

表 T4_1(c1,c2,c3,c4),c4 是SYSDATE
create or replace view v4_1 as select c1,c2,c3 from T4_1
insert into v4_1(c1,c2,c3) values ('手输c1',null,'不能改c4');

复制表的定义及数据

create table t4_2 as select * from t4_1;

用WITH CHECK OPTION 限制数据录入

当约束条件比较简单时,可以直接加在表中,如工资必须大于0

alter table emp add constraints ch_sal check(sal > 0 ); 
insert into 
    (select empno,ename,hiredate)
     from emp
     where hiredate <= SYSDATE WITH CHECK OPTION)
     VALUES 
     (9999,'TEST',SYSDATE+1)
    
     会提示错误

(select empno,ename,hiredate)
from emp
where hiredate <= SYSDATE WITH CHECK OPTION) 是个视图

多表插入语句

无条件INSERT

因为没有加条件,所以会同时向两个表插入数据,且两个表中插入的条数一样

insert all
into emp1(empno,ename) values (empno,ename)
into emp2(empno,deptno) values (empno,ename)
select empno,ename,deptno from emp;

有条件INSERT ALL

insert all
when ename in ('x','t') then 
into emp1(empno,ename) values (empno,ename)
when deptno in ('1','2') then 
into emp2(empno,deptno) values (empno,ename)
select empno,ename,deptno from emp;

有条件INSERT FIRST

当第一个表符合条件后,第二个表将不再插入对应的行

insert first
when ename in ('x','t') then 
into emp1(empno,ename) values (empno,ename)
when deptno in ('1','2') then 
into emp2(empno,deptno) values (empno,ename)
select empno,ename,deptno from emp;

合并记录

merge into bonuses d
using (select employee_id,salary,depart_id
       from employees
       where depart_id = 80
      ) s
    on (d.employee_id = s.employee_id)
    when matched then 
    update 
        set d.bonus = d.bonus + s.salary * 0.01
    when not matched then
    insert 
    (d.employee_id,d.bonus)
    values 
    (s.employee_id,s.salary * 0.01 )

注意事项:
(1)语句是merge into bonuses ,所以在这个语句中只能更改bonuses 的数据,不能改using 后面那些表的数据。
(2)更新,插入两个操作是同时进行的,不分先后。
(3) 在MERGE INTO 语句里不能更新JOIN系列
(4) ON 后面的条件一定要放在括号里,否则会报错
on (d.employee_id = s.employee_id)

删名字重复的记录

通过rowid

delete 
  from dupes a
  where exists (select null from dupes b where b.name = a.name
  and b.rowid > a.rowid)

通过分析函数

delete 
from dupes 
where rowid in (select rid 
             from (select rowid as rid, row_number() over(partition by name order by id) as seq from dupes
             whereseq >1 );
)

使用字符串

生成连续数值

select rownum as rn from emp where rownum <= 3;
select LeveL AS rn from dual CONNECT BY LEVEL <=3;

遍历字符串

select 汉字,LEVEL,substr(汉字,LEVEL,1) as 汉字拆分 from v5_2
connect by LEVEL <= length(汉字);

将字符和数字数据分离

select regexp_replace(data,'[0-9]','') dname,
regexp_replace(data,'[^0-9]','') deptno
from t5_5;

根据表中的行创建一个分割列表

select deptno,
  listagg(ename,',') within group(ORDER BY ename) As total_name
  from emp
  GROUP BY deptno;

生成排名

row_number() over(partition by deptno order by sal desc);
rank() over(partition by deptno order by sal desc);
dense_rank() over(partition by deptno order by sal desc);

row_number() 相同的工资会生成 1,2,3
rank 相同的工资会生成同样的序号 1,1,3
dense_rank() 会生成同样的序号 1,1,2

改写优化案例

不建议使用标量子查询,直接改成left join

可以使用MAX() 代替 rownum =1

参考书籍

Oracle查询优化改写技巧与案例2.0

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
查询优化是数据库性能优化的重要环节之一,而优化改写技巧是提高查询性能的关键手段之一。在Oracle数据库中,有许多查询优化改写技巧案例可以借鉴。 首先,可以利用索引来提高查询性能。索引是数据库中的一种数据结构,它可以加速查询操作。可以通过创建适当的索引来改进查询的执行计划,从而提高查询性能。例如,对于常见的查询字段,可以创建相应的索引,以减少全表扫描的开销。 其次,可以通过优化查询语句来改善查询性能。优化查询语句包括使用合适的JOIN操作、使用子查询和内联视图等。例如,可以使用内联视图来减少查询中的步骤,从而提高查询性能。 此外,可以通过调整数据库参数来改善查询性能。在Oracle数据库中,有许多参数可以配置,以适应不同的查询工作负载。通过合理地配置这些参数,可以提高查询的响应速度。例如,可以调整SGA(System Global Area)和PGA(Program Global Area)的大小,以适应不同的查询需求。 最后,可以通过使用数据库查询优化工具来改善查询性能。Oracle提供了一些查询优化工具,如Explain Plan、SQL Tuning Advisor和Automatic SQL Tuning等。这些工具可以帮助诊断查询性能问题,并提供相应的优化建议。通过使用这些工具,可以快速定位问题并进行优化改写。 总的来说,Oracle查询优化改写技巧案例2.0 PDF提供了一些实用的优化方法和案例,可以帮助开发人员和数据库管理员提高查询性能。通过对这些技巧案例的学习和实践,我们可以更好地优化查询性能,提高数据库的整体性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

涛涛之海

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值