Oracle 课程一之Oracle体系结构

十年热恋 提交于 2020-02-28 07:16:34

课程目标

•理解ORACLE数据库体系架构—内存结构和进程
•理解SQL在数据库中的运作流程
•理解UNDO&REDO原理
•理解commit原理
 

1.Oracle数据库概述

•数据库:物理操作系统文件或磁盘的集合。

•实例:一组Oracle后台进程/线程以及一个共享内存区,这些内存由同一个计算机上运行的线程/进程所共享。

 

2. Oracle体系结构

任何硬件平台或操作系统下的ORACLE体系结构都是相同的,

包括如下四个方面:

•物理结构

数据文件,日志文件,控制文件,参数文件。

•逻辑结构

表空间、段、区间、数据块。

•内存结
共享池,数据缓冲区,日志缓冲区,PGA。
•进程
用户进程、服务器进程、后台进程。
数据文件:select name from v$datafile;
控制文件:select name from v$controlfile;
日志文件:select member from v$logfile;
参数文件:$oracle_home/dbs/initSID.ora(从spfile转换,create pfile from spfile;)
归档日志文件:show parameter log_archive_dest
查看归档模式:archive log list
SGA: show sga/show parameter sga/v$sgastat
PGA: show parameter pga/v$pgastat
进程:ps –ef |grep oracle
查看信息

 

2.1 SGA与PGA

SGA是共享内存区,PGA是私有内存区,用户对数据库发起的无论查询还

是更新的任何操作,都是PGA预先处理,然后接下来才进入实例区域,

由SGA和系列后台进程共同完成用户发起的请求。

PGA的作用主要是三点

•保存用户的连接信息,如会话属性,绑定变量等;
•保存用户权限等重要信息;
•做部分排序操作,如果放不下,就到临时表中完成,就是在磁盘中完成排序。
 

2.2 Shared Pool

 

•Library Cache

library cache最主要的功能就是存放用户提交的SQL语句及相关的解析树(解析树也就是对SQL语句中所涉及的所有对象的展现)、执行计划、用户提交的PL/SQL程序块(包括匿名程序块、存储过程、包、函数等)以及它们转换后能够被Oracle执行的代码等。

library cache也存放了很多的数据库对象的信息,包括表、索引等。有关这些数据库对象的信息都是从dictionary cache中获得的。如果用户对library cache中的对象信息进行了修改,比如为表添加了一个列等,则这些修改会返回到dictionary cache中。

 •DB Dictionary Cache

DICTIONARY CACHE在内存中存放ORACLE数据库中常用的数据字典的信息,若此区域太小,当ORACLE需要某些数据字典信息,如对某用户的权限设置等信息时, 如果该信息不能在DICTIONARY CACHE中找到,则必须先通过物理读从ORACLE数据库的数据文件中得到该信息,然后再将该内存区域的部分信息替换出去。

存放Oracle系统最近使用过的数据块。让他们能够在内存中进行操作。在这个级别里没有系统文件,用户数据文件,临时数据文件,回滚段文件之分。也就是任何文件的数据块都有可能被缓冲。数据库的任何修改都在该缓冲里完成,并由DBWR进程将修改后的数据写入磁盘。

实验1:软解析-测试清理共享池后,执行计划对比

SQL> set autotrace traceonly

SQL> set linesize 2000

SQL> select * from dba_data_files t where t.file_id=2;
View Code
执行计划
----------------------------------------------------------
Plan hash value: 1284839659

------------------------------------------------------------------------------------------------------
| Id  | Operation                         | Name             | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                  |                  |     2 |   812 |     4   (0)| 00:00:01 |
|   1 |  VIEW                             | DBA_DATA_FILES   |     2 |   812 |     4   (0)| 00:00:01 |
|   2 |   UNION-ALL                       |                  |       |       |            |          |
|   3 |    NESTED LOOPS                   |                  |     1 |   399 |     2   (0)| 00:00:01 |
|   4 |     MERGE JOIN CARTESIAN          |                  |     1 |   381 |     1   (0)| 00:00:01 |
|   5 |      NESTED LOOPS                 |                  |     1 |    71 |     1   (0)| 00:00:01 |
|*  6 |       TABLE ACCESS BY INDEX ROWID | FILE$            |     1 |    32 |     1   (0)| 00:00:01 |
|*  7 |        INDEX UNIQUE SCAN          | I_FILE1          |     1 |       |     0   (0)| 00:00:01 |
|*  8 |       FIXED TABLE FIXED INDEX     | X$KCCFE (ind:1)  |     1 |    39 |     0   (0)| 00:00:01 |
|   9 |      BUFFER SORT                  |                  |     1 |   310 |     1   (0)| 00:00:01 |
|* 10 |       FIXED TABLE FULL            | X$KCCFN          |     1 |   310 |     0   (0)| 00:00:01 |
|  11 |     TABLE ACCESS CLUSTER          | TS$              |     1 |    18 |     1   (0)| 00:00:01 |
|* 12 |      INDEX UNIQUE SCAN            | I_TS#            |     1 |       |     0   (0)| 00:00:01 |
|  13 |    NESTED LOOPS                   |                  |     1 |   473 |     2   (0)| 00:00:01 |
|  14 |     MERGE JOIN CARTESIAN          |                  |     1 |   455 |     1   (0)| 00:00:01 |
|  15 |      MERGE JOIN CARTESIAN         |                  |     1 |   364 |     1   (0)| 00:00:01 |
|  16 |       NESTED LOOPS                |                  |     1 |    54 |     1   (0)| 00:00:01 |
|* 17 |        TABLE ACCESS BY INDEX ROWID| FILE$            |     1 |    15 |     1   (0)| 00:00:01 |
|* 18 |         INDEX UNIQUE SCAN         | I_FILE1          |     1 |       |     0   (0)| 00:00:01 |
|* 19 |        FIXED TABLE FIXED INDEX    | X$KCCFE (ind:1)  |     1 |    39 |     0   (0)| 00:00:01 |
|  20 |       BUFFER SORT                 |                  |     1 |   310 |     1   (0)| 00:00:01 |
|* 21 |        FIXED TABLE FULL           | X$KCCFN          |     1 |   310 |     0   (0)| 00:00:01 |
|  22 |      BUFFER SORT                  |                  |     1 |    91 |     1   (0)| 00:00:01 |
|* 23 |       FIXED TABLE FIXED INDEX     | X$KTFBHC (ind:1) |     1 |    91 |     0   (0)| 00:00:01 |
|  24 |     TABLE ACCESS CLUSTER          | TS$              |     1 |    18 |     1   (0)| 00:00:01 |
|* 25 |      INDEX UNIQUE SCAN            | I_TS#            |     1 |       |     0   (0)| 00:00:01 |
------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   6 - filter("F"."SPARE1" IS NULL)
   7 - access("F"."FILE#"=2)
   8 - filter("FE"."FENUM"=2)
  10 - filter("FNNAM" IS NOT NULL AND "FNFNO"=2 AND "FNTYP"=4 AND
              "INST_ID"=USERENV('INSTANCE') AND BITAND("FNFLG",4)<>4)
  12 - access("F"."TS#"="TS"."TS#")
  17 - filter("F"."SPARE1" IS NOT NULL)
  18 - access("F"."FILE#"=2)
  19 - filter("FE"."FENUM"=2)
  21 - filter("FNNAM" IS NOT NULL AND "FNFNO"=2 AND "FNTYP"=4 AND
              "INST_ID"=USERENV('INSTANCE') AND BITAND("FNFLG",4)<>4)
  23 - filter("HC"."KTFBHCAFNO"=2)
  25 - access("HC"."KTFBHCTSN"="TS"."TS#")


统计信息
----------------------------------------------------------
        276  recursive calls
          1  db block gets
         50  consistent gets
          0  physical reads
          0  redo size
       1172  bytes sent via SQL*Net to client
        338  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
         10  sorts (memory)
          0  sorts (disk)
          1  rows processed
View Code
SQL>alter system flush shared_pool;   --- (测试清理共享池后的执行计划禁止在公司测试环境执行)

SQL>select owner,name,type,kept,sharable_mem,pins,locks,LOADS from v$db_object_cache where name like '%dba_data_files%';

SQL> select * from dba_data_files t where t.file_id=2;
View Code
执行计划
----------------------------------------------------------
Plan hash value: 1284839659

------------------------------------------------------------------------------------------------------
| Id  | Operation                         | Name             | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                  |                  |     2 |   812 |     4   (0)| 00:00:01 |
|   1 |  VIEW                             | DBA_DATA_FILES   |     2 |   812 |     4   (0)| 00:00:01 |
|   2 |   UNION-ALL                       |                  |       |       |            |          |
|   3 |    NESTED LOOPS                   |                  |     1 |   399 |     2   (0)| 00:00:01 |
|   4 |     MERGE JOIN CARTESIAN          |                  |     1 |   381 |     1   (0)| 00:00:01 |
|   5 |      NESTED LOOPS                 |                  |     1 |    71 |     1   (0)| 00:00:01 |
|*  6 |       TABLE ACCESS BY INDEX ROWID | FILE$            |     1 |    32 |     1   (0)| 00:00:01 |
|*  7 |        INDEX UNIQUE SCAN          | I_FILE1          |     1 |       |     0   (0)| 00:00:01 |
|*  8 |       FIXED TABLE FIXED INDEX     | X$KCCFE (ind:1)  |     1 |    39 |     0   (0)| 00:00:01 |
|   9 |      BUFFER SORT                  |                  |     1 |   310 |     1   (0)| 00:00:01 |
|* 10 |       FIXED TABLE FULL            | X$KCCFN          |     1 |   310 |     0   (0)| 00:00:01 |
|  11 |     TABLE ACCESS CLUSTER          | TS$              |     1 |    18 |     1   (0)| 00:00:01 |
|* 12 |      INDEX UNIQUE SCAN            | I_TS#            |     1 |       |     0   (0)| 00:00:01 |
|  13 |    NESTED LOOPS                   |                  |     1 |   473 |     2   (0)| 00:00:01 |
|  14 |     MERGE JOIN CARTESIAN          |                  |     1 |   455 |     1   (0)| 00:00:01 |
|  15 |      MERGE JOIN CARTESIAN         |                  |     1 |   364 |     1   (0)| 00:00:01 |
|  16 |       NESTED LOOPS                |                  |     1 |    54 |     1   (0)| 00:00:01 |
|* 17 |        TABLE ACCESS BY INDEX ROWID| FILE$            |     1 |    15 |     1   (0)| 00:00:01 |
|* 18 |         INDEX UNIQUE SCAN         | I_FILE1          |     1 |       |     0   (0)| 00:00:01 |
|* 19 |        FIXED TABLE FIXED INDEX    | X$KCCFE (ind:1)  |     1 |    39 |     0   (0)| 00:00:01 |
|  20 |       BUFFER SORT                 |                  |     1 |   310 |     1   (0)| 00:00:01 |
|* 21 |        FIXED TABLE FULL           | X$KCCFN          |     1 |   310 |     0   (0)| 00:00:01 |
|  22 |      BUFFER SORT                  |                  |     1 |    91 |     1   (0)| 00:00:01 |
|* 23 |       FIXED TABLE FIXED INDEX     | X$KTFBHC (ind:1) |     1 |    91 |     0   (0)| 00:00:01 |
|  24 |     TABLE ACCESS CLUSTER          | TS$              |     1 |    18 |     1   (0)| 00:00:01 |
|* 25 |      INDEX UNIQUE SCAN            | I_TS#            |     1 |       |     0   (0)| 00:00:01 |
------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   6 - filter("F"."SPARE1" IS NULL)
   7 - access("F"."FILE#"=2)
   8 - filter("FE"."FENUM"=2)
  10 - filter("FNNAM" IS NOT NULL AND "FNFNO"=2 AND "FNTYP"=4 AND
              "INST_ID"=USERENV('INSTANCE') AND BITAND("FNFLG",4)<>4)
  12 - access("F"."TS#"="TS"."TS#")
  17 - filter("F"."SPARE1" IS NOT NULL)
  18 - access("F"."FILE#"=2)
  19 - filter("FE"."FENUM"=2)
  21 - filter("FNNAM" IS NOT NULL AND "FNFNO"=2 AND "FNTYP"=4 AND
              "INST_ID"=USERENV('INSTANCE') AND BITAND("FNFLG",4)<>4)
  23 - filter("HC"."KTFBHCAFNO"=2)
  25 - access("HC"."KTFBHCTSN"="TS"."TS#")


统计信息
----------------------------------------------------------
        858  recursive calls
          1  db block gets
        165  consistent gets
          0  physical reads
          0  redo size
       1172  bytes sent via SQL*Net to client
        338  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
         13  sorts (memory)
          0  sorts (disk)
          1  rows processed
View Code

 

 •DB Buffer Cache

 

存放Oracle系统最近使用过的数据块。让他们能够在内存中进行操作。在这个级别里没有系统文件,用户数据文件,临时数据文件,回滚段文件之分。也就是任何文件的数据块都有可能被缓冲。数据库的任何修改都在该缓冲里完成,并由DBWR进程将修改后的数据写入磁盘。

实验2:刷新DB Buffer Cache

 

X$BH   --- Buffer状态

 

alter system set events = 'immediate trace name flush_cache';

SQL> create table test_buffer as select * from dba_objects;

表已创建。

SQL> exec dbms_stats.gather_table_stats(user,'test_buffer');

表已分析。

SQL> select blocks,empty_blocks from dba_tables where table_name='TEST_BUFFER' and owner='SYS';

    BLOCKS EMPTY_BLOCKS
---------- ------------
       688           79
SQL> select count(*) from x$bh;

  COUNT(*)
----------
      8835

SQL> select count(*) from x$bh where state = 0;

  COUNT(*)
----------
        29

SQL> alter system set events = 'immediate trace name flush_cache';

系统已更改。

SQL> select count(*) from x$bh where state = 0;

  COUNT(*)
----------
      8832

SQL> set autotrace traceonly
SQL> select count(*) from test_buffer;


执行计划
----------------------------------------------------------
Plan hash value: 2550671572

--------------------------------------------------------------------------
| Id  | Operation          | Name        | Rows  | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |             |     1 |   154   (2)| 00:00:02 |
|   1 |  SORT AGGREGATE    |             |     1 |            |          |
|   2 |   TABLE ACCESS FULL| TEST_BUFFER | 50081 |   154   (2)| 00:00:02 |
--------------------------------------------------------------------------


统计信息
----------------------------------------------------------
          1  recursive calls
          0  db block gets
        693  consistent gets
        689  physical reads
          0  redo size
        410  bytes sent via SQL*Net to client
        385  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

SQL> /


执行计划
----------------------------------------------------------
Plan hash value: 2550671572

--------------------------------------------------------------------------
| Id  | Operation          | Name        | Rows  | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |             |     1 |   154   (2)| 00:00:02 |
|   1 |  SORT AGGREGATE    |             |     1 |            |          |
|   2 |   TABLE ACCESS FULL| TEST_BUFFER | 50081 |   154   (2)| 00:00:02 |
--------------------------------------------------------------------------


统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
        693  consistent gets
          0  physical reads
          0  redo size
        410  bytes sent via SQL*Net to client
        385  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed
View Code

 

 Redo Log Buffer

重做日志文件的缓冲区,对数据库的任何修改都按顺序被记录在该缓冲,然后由LGWR进程将它写入Redo log files。这些修改信息包含DML语句以及DDL语句。 重做日志缓冲区的存在是因为内存到内存的操作比较内存到硬盘的速度快很多,所以重作日志缓冲区可以加快数据库的操作速度,但是考虑的数据库的一致性与可恢复性,数据在重做日志缓冲区中的滞留时间不会很长。

2.3 数据库进程

  • PMON

PMON(processes Mointor),是进程监视器。如果执行某些更新语句,未提交时进程崩溃,这时PMON会自动回滚该操作,无需人工执行rollback命令。除此之外还可以干预后台进程,比如RECO异常失败了,此时PMON会重启RECO进程,如果遇到LGWR进程失败这种严重的问题,PMON会做出中止实例这个激烈的动作,用于防止数据错乱。

  • SMON

SMON(System Monitor),系统监视器,与PMON不同的是,SMON关注的是系统级的操作而非单个进程,重点工作在于实例恢复,除此以外还有清理临时表空间、清理回滚段空间、合并空闲空间等。

  • CKPT

 CKPT(Checkpoint Process),检查点进程。由Oracle的fast_start_mttr_target参数控制,用于触发DBWR从数据缓冲中写出数据到磁盘。CKPT执行越频繁,DBWR写出最频繁,性能越低,但数据库异常恢复的时候会越快。

  • RECO

RECO(Distributed Database Recovery)用于分布式数据库恢复。适用于两阶段提交场景。

  • DBWR

DBWRn(Database Block Writer)数据库块写入器是Oracle最核心的进程之一,负责把数据从数据缓存区写到磁盘,改进程和CKPT相辅相成,因为是CKPT促成DBWR去写的。不过DBWR也和LGWR密切相关,因为DBWR要想把数据缓存区数据写到磁盘时,必须通知LGWR先完成日志缓存区写到磁盘的动作后,方可开工。

  • LGWR
LGWR(Log Writer)日志写入器,就是将日志缓存区的数据从内存写到磁盘的redo文件中。Redo的记录可以用来做数据库的异常恢复,只要保护好这些redo文件和后续对于的归档文件,从理论上来讲,即使数据文件都被删光了,可以根据这些日志将曾经发生的事情全部重做一遍,从而保证数据库的安全。
LGWR必须记录下所有从数据缓存区写到数据文件的动作,工作任务相当繁重。由于要顺序记录情况下保留的日志才有意义,多进程难以保证顺序,因此只能采用单线程。为了适应工作高强度的日志记录工作,LGWR制定了5条规则:
–每隔三秒钟,LGWR运行一次;
–任何commit触发LGWR运行一次;
–DBWR要把数据从数据缓存写到磁盘,触发LGWR运行一次;
–日志缓存区满三分之一或记录慢1MB,触发LGWR运行一次;
–联机日志文件切换也将触发LGWR。
  • ARCn

ARCn(Archive Process)归档进程,它的作用是在LGWR写日志写到需要覆盖重写的时候,触发ARCH进程去转移日志文件,复制出去形成归档日志文件。

2.4 各类型SQL的操作流程

SELECT语句操作流程:

•Select * from test  where  object_id=200在体系中是如何运转的。
•1. 在PGA中把此条SQL语句hash成一个值;
•2. 接下来根据此hash值到SGA的共享池中去匹配,如果没有,首先查询自己的语句语法是否正确,语义是否正确,是否有权限。如果都通过则通过CBO解析生成执行计划(如走索引还是全表)。
•3. 如果是走索引,到数据缓存区找到object_id=200的索引,根据索引rowid找到记录,如果数据缓存区找不到,则到数据文件中找到,并展示给用户。
 
UPDATE语句操作流程:
•Update test set object_id = 100 where object_id = 200; 在体系中是如何运转的。
•更新object_id=200的记录首先要查到object_id=200的记录,检查object_id=200是否在数据缓存中,不在则从磁盘中读取到数据缓存中。
•在回滚表空间的相应回滚段事务表上分配事务槽,从而在回滚表空间分配到空间。该动作需要记录redo日志。
•在数据缓存区中创建object_id=200的前镜像,前镜像数据也会写进磁盘的数据文件(undo表空间的数据文件),从缓存区写进磁盘有CKPT决定,当然这些动作都要记录redo日志。
•前面的步骤做完了,才允许object_id=200改为object_id=100,记录redo日志。
•此时用户如果执行了提交,日志缓存区立即记录这个提交信息,然后将回滚段事务标记为非激活INACTIVE状态,表示允许重写。
•如果执行了回滚,Oracle需要从回滚段中将前镜像object_id=200的数据读出来,修改数据缓存区,完成回滚,记录redo日志。

DELETE的运作流程:

 

3 COMMIT做了什么

实验3.1:是不是事务越大,commit时间越长?如插入10万条数据后commit的时间比插入100条数据后commit所耗的时间要长吗?

SQL> create table test(x int);

SQL> set timing on

SQL> insert into test select rownum from dual connect by level <= 100;

已用时间:  00: 00: 00.12

SQL> commit;

已用时间:  00: 00: 00.00

SQL> create table test1(x int);

SQL> insert into test1 select rownum from dual connect by level <= 1000000;

已创建1000000行。

已用时间:  00: 00: 00.89

SQL> commit;

已用时间:  00: 00: 00.01
View Code

实验3.2:

循环提交的问题,先得说commit开销的两个因素:

1.显然会增加与数据库的往返通信,如果每个记录都提交,生成的往返通信量就会大得多。

2.每次提交时,必须等到redo写至磁盘。就会导致等待,这种等待称为日志文件同步(log file sync)。

SQL>create table test(x int);
SQL>set timing on
SQL>declare 
   a number;
begin 
    for i in 1.. 100000
       loop
        execute immediate 'insert into test values(:a)'using i;
    commit;
    end loop;
end;
/

SQL>truncate table test;
SQL>declare 
   a number;
begin 
    for i in 1.. 100000
       loop
        execute immediate 'insert into test values(:a)'using i;
    end loop;
    commit;
end;
/
View Code

思考:

1.在执行一条update语句提交后,数据会写到数据文件中吗?

2.在执行一条update语句后一直未提交,数据会写到数据文件中吗?

 

4 一致性查询及一致性读原理

Select * from test where object_id = 2;

  如果8点钟可以查询出两条记录,假设一下,如果此查询很慢,从8点开始查,9点才能结束。在此期间不巧被删了一条数据,请问最终返回的结果是一条数据还是两条数据?

  假设我有4个户头,户1余额为1000元,户2余额为2000元,户3余额为3000元,户4余额为4000元,总计是1万元。现在查询账号的总余额,从户1开始已经读完户3,就在此时户1转了1000元到户4,此时户4是5000,如果此时户4读当前的余额,那总余额为1000+2000+3000+5000=11000。现在可以给出结论是查8点的数据还是9点的数据吧。

  一致读的原理:及时查询的记录由查询的这一时间点决定,后面即使变化了,也要根据回滚段保存的前镜像记录,取得那个时间点的数据。

数据库是怎么保证一致读呢?

首先了解以下两个前提:

•1. 了解数据库的SCN(System change Number),是数据库内部的时钟,可以与时间相互转换,是一个只会增加不会减少的数字,存在于Oracle的最小单位块里,当某块改变时SCN就会递增。
•2. 数据库的回滚记录事务槽,如果你更新了某块,事务就被写进事务槽里。如果未提交或回滚,改块就存在活动事务,数据库读到此块可以识别到这种情况的存在。
 
5 学习Oracle体系结构的意义:

1. PGA是用来排序的,当PGA空间不够时只有用磁盘排序,如果一个大排序不仅非常耗CPU,而且会影响其他的排序,就是影响其他的功能慢。想想我们系统中的排序,排序在设计或开发阶段就很随意,大的排序也不避讳。

2. DBWR写磁盘的前提条件是保证对应的redo已经写到磁盘,我们可以把最繁忙的进程LGWR写redo log放到最快的磁盘上,同时也可以提高commit的速度。

3. 避免循环commit提交。LGWR是单线程的顺序写,如果有大量的循环提交,那log buffer基本没有用处,大量commit排队提交,commit慢了造成锁释放慢,在系统大并发下,性能是不是有问题。

4. 如有一个很大的数据库,数据量庞大,访问量非常高,而共享池很小,会产生很多SQL硬解析,因为解析的SQL很快就被挤出共享池。

5. 如果你诊断一个数据库共享池总不够用,进一步发现硬解析很高,那就要用变量。

6. 上班时间导入数据和大量操作数据有什么影响?产生大量的redo,会影响其他功能慢。导出也会影响性能,以后再讲。

7. 在用as of timestap恢复数据的时候,发生快照失效,原因是什么,undo中没有改记录的改动了。如何解决,可以增大undo_retention,也可以增大undo表空间大小。

6 课后作业:

结合体系结构做一次性能调优

创建一张表,向表中插入10万条数据,开发人员的实现如下所示:

create table t (x  int);

alter system flush shared_pool;

create or replace procedure proc1

as

begin

  for i in 1.. 100000

           loop

  execute immediate ‘insert into t values(‘||i||’)’;

         commit;

     end loop;

     end;

     /
View Code

•找出优化点,并分析出原因,执行的时间

•可以颠覆实现,给出执行时间
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!