上周学习oracle SQL 编程的前两章,今天做一下总结。
一、多表插入和merge
1.以前学的是MYSQL, 没有遇到多表插入,以及merge合并更新和插入语句的情况,所以看起来还是比较新颖的。
多表插入
insert all/first when cond1 into tab_1 when cond2 into tab_2 else into tab_3 <data_or_selec_clause>
中 insert all 是每一条记录和所有的判定条件进行一次匹配,匹配成功则进行插入,也就是说一条记录可能会进行多次插入。
而insert first 则是每一条记录只在第一次匹配成功时进行插入操作。
2.merge语句
格式:
需要注意的是在oracle 9版本中when matched 和when not matched是不可或缺的,在oracle 10及以上版本二者是可选的。
且今天在公司的oracle 9机子上试过了,在when matched 中包含delete语句时会报错,update和insert语句包含where条件
时也会报缺少关键字的错误。
但是网上说oracle 10是可以加入where条件的,并且delete语句也是可选的。
二、SQL语句执行
0. SQL执行前的处理过程
>> 语法检查
>> 语义检查
诸如SQL中访问的对象是否存在和用户是否具备相应的权限访问
>> 解析SQL语句
利用内部算法进行解析,生成解析树和执行计划
>> 执行SQL,返回结果
1. 软解析和硬解析
硬解析是指待执行的SQL之前没有执行过,需要利用内部算法执行所有工作为SQL生成解析树、执行计划后,再执行
软解析是指待执行的SQL语句已经在库高速缓存中存在了,执行时直接提取对应的执行计划进行执行。
注意:SQL 语句大小写不同或者某个地方多个空格都会单独的进行硬解析存入共享池,例如
select * from a 和 select * from a 就具有不同的hash散列值,不能算是相同的SQL
select * from a 和 SELECT * FROM A也具有不同的hash散列值,不能算作相同的sql
但是使用参数绑定,绑定不同的值时算作相同的SQL
如:
variable v_a number;
exec :v_a := 3;
select * from a where a.b=:v_a;
和v_a设置成5时具有相同的hash散列值,算作相同的SQL
2. 查询转换
——发生在语法、语义检查过后,sql执行之前
——查询转换包含以下几种
——视图合并
发生外部查询块谓语包含下列项的场合:
能够在另一个查询块的索引中使用的列
能够在另一个查询的分区截断中使用的列
在一个联接视图中能够限制返回行数的条件
可加入提示/*+ NO_MERGE */ 来禁止
加入提示/*+ MERGE */ 来强制进行视图合并
查询块包含解析函数、聚合函数、集合运算、order by 子句或使用rownum时视图合并被禁止
——子查询解嵌套
filter运算和nested loops连结效率对比
可加入提示/*+ NO_UNNEST */来禁止解嵌套
——谓语前推
用来将谓语从一个内含查询块中应用到不可合并的查询块中。既尽可能早的过滤掉不需要的数据
——使用物化视图进行查询重写
查询重写是一种发生在当一个查询或查询的一部分已经被保存为一个物化视图,转换器重写该查询以使用预先算好
的物化视图数据而不需要执行当前查 询的转换。
物化视图与普通视图的差别在于物化视图的查询已经被执行并将结果集存入一张表中。
3.确定执行计划
在确定使用哪个执行计划之前,oracle会计算各个执行计划的成本值,选择成本值最小的一个进行执行。
4.执行计划并取得数据
其实不管我们平时使用有没有使用limit限制返回结果行数,我们每次从服务器获取的记录条数都是固定的,这个值可以
通过set arraysize n_number 来设置。
比如我们有如下查询
select * from game
game中有1000行数据,现在我们环境中arraysize 为20 则我们实际上与服务器进行的交互访问在50次以上
5.SQL执行——总览