Oracle查询优化读书笔记
本文为读书笔记<<Oracle查询优化改写2.0技巧与案例》-电子工业出版社(有教无类、落落著)
---------------------------------------------------基础----------------------------------------------------------------------------------
1、空值:查询(is null)、处理空值(NVL(null,0)、COALESCE(null,null,0))、空值不支持运算(+-*/ 比较 相等) 查询为空、排序(升序在后降,手动更改:nulls first)、'' is null(为true)
2、别名:AS 引用别名要再嵌套一层
3、拼接:||' '=>生成sql语句
4、列排序:列名(DESC ASC)、 序号(从1开始)、 多列排序(从左至右)、随机排序(dbms_random.value)、条件排序(order by case when..)
5、关联连接:INNER JOIN(两表匹配)、LEFT JOIN(左表所有,右表匹配)、RIGTH JOIN(右表所有,左表匹配)、FULL JOIN(全部数据)
用(+) LEFT JOIN (+号在右表上) 链接与过滤条件(先过滤再JOIN 、先JOIN再关连)
6、多表插入:无条件INSERT 、有条件INSERT ALL WHEN THEN INTO 、INSERT FIRST WHEN THEN、转置:Isert all into t1() values ('',仁) 同价于union all :不同列的数据插入到同一表中
7、批量更新:MERGE INTO EMP USING(select ...) DEPT ON (条件) when mathed then update set ... when not mathecd then insert ()
8、树形查询:select LEVEL,(PRIOR 上级信息) from emp start with 开始条件 CONNECT BY LEVEL (PRIOR ID)=parentId
connect_by_isleaf isleaf:是否叶节点
sys_connect_by_path(t.orgname,','):',
排序:order SIBLINGS BY
select level,t.orgname ,sys_connect_by_path(t.orgname,',') from AUTH_ORG t where connect_by_isleaf=1 start with t.parentid='-1' connect by (prior t.id)=t.parentid order siblings by t.sortcode
9、分页排序:select rn,ename from (select rownum as rn,ename from (select ename from emp where .. order by ..) x where rownum<=10)) where rn>=6
select ename,rn from( select ename,row_number() over(patition deptid order by sal)as rn,ename from emp where)x where rn between 6 and 10;
10、partition by:分析函数,可以与聚合函数一起配合使用,OVER (PARTITION BY子句 ORDER BY子句 ROWS/RANGE子句),
rows与range窗口子句:如果分析函数没有指定ORDER BY子句,也就不存在ROWS/RANGE窗口的计算,range是逻辑窗口,是指定当前行对应值的范围取值,列数不固定,只要行值在范围内,对应列都包含在内;rows是物理窗口,即根据order by 子句排序后,取的前N行及后N行的数据计算
unbounded:无界限 preceding:从分区第一行头开始,则为 unbounded。 N为:相对当前行向前的偏移量 following :与preceding相反,到该分区结束,则为 unbounded。N为:相对当前行向后的偏移量 current row:顾名思义,当前行,偏移量为0
PARTITION BY W_PURCH_SCHEDULE_LINE_F.PRODUCT_WID ORDER BY TRUNC(W_DAY_D.DAY_DT) RANGE BETWEEN INTERVAL '2' day preceding and INTERVAL '1' day following
常用分析函数:row_number() sum() max() count()
11、包结构:包含两部分包规范和包体,包定义PACKAGE:包内公有元素(类型 变量名等) 包体PACKAGE BODY:包的实现
12、管道函数:可以返回行集合,可以像查询物理表一样查询它或者将其赋值给集合变量;PRAGMA AUTONOMOUS_TRANSACTION使用自治事务使管道函数作为独立事务处理; 最后空返回:return;
13、%TYPE定义方式:一个变量的数据类型与另一个已经定义了的变量(尤其是表的某一列)的数据类型 %ROWTYPE:使一个变量的数据类型与一个表中记录的各个列的数据类型相对应、一致
14、游标: sys_refcursor; open cur for select * from t ; loop fetch cur into v_row exit when cur%NOTFOUND(v_cur%notfound有三种状态,true,false,null) pipe ROW(v_row) end loop; close cur;
15、
---------------------------------------------------技巧----------------------------------------------------------------------------------
1、删除名称重复的记录:DELETE FROM TABLE T WHERE EXISTS(SELECT NULL FROM TABLE B WHERE B.NAME=T.NAME AND T.ROWID>B.ROWID)
2、计算字符在字符串中出现的次数:regexp_count(srcstr,pattern,position,modifer)
3、删除字符串中不需要的字符:TRANSLATE(str,'1'||replace,'1') regexp_replace(str,'[replace]')
4、行变分隔列表:listagg(t.username,',') within group(order by t.no)
5、复制表:create table t_2 as select * from t where 1=2
6.
---------------------------------------------------执行计划----------------------------------------------------------------------------------
explain plan --sql select * from table(dbms_xplan.display());
1、执行计划是一条查询语句在Oracle中的执行过程或访问路径的描述
2、列的管理: 工具 —> 首选项 —> 窗口类型 —> 计划窗口 —> 根据需要配置要显示在执行计划中的列
基数(Rows):Oracle估计的当前操作的返回结果集行数
字节(Bytes):执行该步骤后返回的字节数
耗费(COST)、CPU耗费:Oracle估计的该步骤的执行成本,用于说明SQL执行的代价,理论上越小越好(该值可能与实际有出入)
时间(Time):Oracle估计的当前操作所需的时间
3、常见描述:
表访问的几种方式:(非全部):表上存在选择性很好的索引,却走了全表扫描,而且是大表的全表扫描,就说明表的访问方式可能存在问题,大表上没有合适的索引而走了全表扫描,就需要分析能否建立索引,或者是否能选择更合适的表连接方式和连接顺序以提高效率。
TABLE ACCESS FULL(全表扫描)
TABLE ACCESS BY ROWID(通过ROWID的表存取)
TABLE ACCESS BY INDEX SCAN(索引扫描)
索引扫描又分五种:
INDEX UNIQUE SCAN(索引唯一扫描)
INDEX RANGE SCAN(索引范围扫描)
INDEX FULL SCAN(索引全扫描)
INDEX FAST FULL SCAN(索引快速扫描)
INDEX SKIP SCAN(索引跳跃扫描)
4、hint:详见:https://www.cnblogs.com/emilyyoucan/p/7844795.html(hurong)
5、Oracle优化器:基于规则的优化方式(Rule-Based Optimization,简称为RBO)、基于代价的优化方式(Cost-Based Optimization,简称为CBO)
默认:Choolse:默认的情况下Oracle用的便是这种方式。指的是当一个表或或索引有统计信息,则走CBO的方式,如果表或索引没统计信息,表又不是特别的小,而且相应的列有索引时,那么就走索引,走RBO的方式。