读书笔记系列 01-《收获、不止 Oracle》 最近计划将看过的 Oracle 书籍依次系统的总结下读书笔记。 这本书是我个人觉得写的最有趣的 Oracle 书籍,也是我接触 Oracle 后第一本完全精读的 Oracle 中文书籍。全书主要讲述了 Oracle 的基本原理(物理体系结构、逻辑体系结构)、表设计、索引原理、多表连接等内容。该书最大特点是利用诙谐的课堂氛围以及将枯燥的技术与有趣多生活故事做类比,培养了读者正确学习和应用技术的意识,达成目标的前提下,尽可能的少做事才能更高效。今后学习一门技术,甚至是一个知识点,都要思考为什么要学它,它是解决什么问题的。这些道理应用广泛,不止局限于学习 Oracle 技术。
1.1 Oracle 物理体系 书中通过类比生活实例,小余一家,爸爸开服装店,妈妈在学校旁边开餐饮店,引出 Oracle 物理体系,趣味性十足。
1 区:PGA、2 区:Instance(SGA + 后台进程)、3 区:Database(各类文件)
通过语句执行过程体会 Oracle 体系结构: 查询语句 (select) 执行过程:在 1 区准备,完成用户连接信息的保存和权限保存,生成一个唯一的 hash 值,进入 2 区,首先是到共享池处理,此 hash 值没有,则需要检查语法语义权限解析生成执行计划,然后进入数据缓冲区查询,如果没有,则数据缓冲区从数据文件中查到并带回数据缓冲区,最终呈现给用户。 修改语句 (update, insert, delete) 执行过程:查询语句有的过程都有,在数据缓冲区找到要修改的块,修改之前生成前镜像(CR 块),修改后提交,LGWR 进程将 log buffer 条目写入 redo logfile,而至于 DBWR 进程何时将修改数据写入磁盘,是不确定的。
undo 的作用:事物回滚、一致性读 (构造 CR 块) redo 的作用:对数据库所有操作进行记录,日志写优先原则,数据库快速提交,异常断电也不会数据丢失。
思考题: 1) 修改语句 (update, insert, delete),哪类语句产生的 undo 最多?哪类语句产生的 redo 最多? 参考答案:一般来讲,因为 undo 记录的是反向操作。 insert 的反向操作是 delete,undo 只需要记录 delete 行的 rowid 即可,所以 insert 产生的 undo 最少; delete 的反向操作是 insert,undo 需要记录 insert 所有字段的值,所以 delete 产生的 undo 最多; update 介于二者之间。 注意:undo 条目也是被 redo 记录的。
2)ORA-01555 原因和解决方案? 参考答案:原因是 Oracle 查询要保证一致性读,而当查询语句执行时间较长,很可能后面要查询块的 undo 信息已经被覆盖,导致无法构造一致性读需要的 cr 块。oracle 会抛出 ORA-01555 错误。 解决方案:
a. 优化该查询 SQL,缩短其执行时间;
b. 增加 undo_retention 值,并且设置该 undo 表空间为 guarantee(alter tablespace undotbs1 retention guarantee;)。
1.2 Oracle 逻辑体系 书中通过类比生活实例,王财主的农场(database),出租给不同养殖户(tablespace),每个养殖户又各自养殖牛、羊、猪(segment)等。王财主心中以 8 平米为最小核算单元(block),谁的养殖空间不够向王财主申请空间(extent),不管空间多紧张,王财主特别有原则的留了 3 个农场:系统农场(系统表空间)、临时农场(临时表空间)、回滚农场(回滚表空间),给各个养殖户提供方便。通过这一系列简单易懂的小事情,引出 Oracle 逻辑体系,让人形象的了解 oracle 表空间、段、区、块的概念。 可以建表插入数据,然后通过 dba_extents, dba_segments, dba_tablespaces 体会逻辑结构。
1.3 学习体系结构的意义 这也是全书的点睛之笔,凡事学完都探讨其意义。 如果只是单纯讲述体系结构,我之前学习的体系结构笔记实际上内容更加详尽:
- --需要优化的存储过程:
- create or replace procedure proc1
- as
- begin
- for i in 1 .. 100000
- loop
- execute immediate 'insert into t values ('||i||')';
- commit;
- end loop;
- end;
- /
- --执行存储过程
- drop table t purge;
- create table t(x int);
- alter system flush shared_pool;
- set timing on
- exec proc1;
- --查询解析
- select sql_id, sql_text, parse_calls, executions from v$sql where sql_text like '%insert into t values%';
然后进一步从绑定变量、静态改写、批量提交、集合写法、直接路径、并行设置一步步最终体验优化到飞船速度。这里只将重要的优化步骤总结下,具体可以参考原书内容:
- --优化手段:使用绑定变量 + 批量提交
- create or replace procedure proc3
- as
- begin
- for i in 1 .. 100000
- loop
- execute immediate 'insert into t values (:n)' using i;
- end loop;
- commit;
- end;
- /
- --优化手段:集合写法 + 直接路径 + 并行设置 + nologging
- create table t nologging parallel 16 as select rownum x from dual connect by level <= 1000000;
虽然是精心构造的测试用例,但是实际优化工作中实际上很多也是由上面的一个或多个技术手段来调整的。
- @?/rdbms/admin/utlchain.sql
- analyze table t list chained rows into chained_rows;
- select count(*) from chained_rows where table_name = 'T';
查询有记录就证明存在行迁移。
来源: http://www.cnblogs.com/jyzhao/p/6893476.html