Oracle学习笔记二----应用实践一

来源:互联网 发布:时间自动同步软件 编辑:程序博客网 时间:2024/06/08 15:16

Oracle实践

alter system flush shared_pool; 清空共享池

show parameter undo 查看回滚段的相关参数(undo_management AUTO表示自动管理回滚段空间,undo_retention 900 表示commit900秒后,前镜像空间允许覆盖, undo_tablespace UNDOTBS1表示回滚段表空间名字)

show parameter db_block_size; 查询数据块的大小 或者 select block_size from dba_tablespaces where tablespace_name='SYSTEM';

  • 创建表空间:

create tablespace TBS_LJB_16k

blocksize 16K

datefile 'E:\ORADATA\ORA10\DATAFILE\TBS_LJB_16k_01.DBF‘ size 100M

autoextend on

extent managent local

segment space management auto;

 

共享池中缓存下来的SQL语句以及HASH出来的唯一值,都可以在v$sql中对应的SQL_TEXT和SQL_ID字段中查询到,而解析的次数和执行的次数则保存在PARSE_CALL和EXECUTIONS中,如:

select t.sql_text,t.sql_id,PARSE_CALLS,t.EXECUTIONS from v$sql t where sql_text like '%insert into t values%';

语句优化:

sqlplus ljb/ljb

drop table t purge;

create table t (x int);

原始SQL语句:

create or replace procedure proc1

as

begin

    for i in 1 ..100000

    loop

        execute immediate

        'insert into t values('||i||')';   -- ||在这里是一个连接符,'insert into t values ('作为一个字符串  ||  变量i || 字符串')' 

    commit;

    end loop;

end;

/

----绑定变量优化

查询数据共享池中执行过的SQL语句,发现每次插入都生成一个不同的HASH值,需要重新解析,解析了10万次。这里考虑使用变量代替插入的具体值,使之解析一次。

create or replace procedure proc2

as

begin

    for i in 1 ..100000

    loop

        execute immediate

        'insert into t values(:x)' using i;

    commit;

    end loop;

end;

/

----尽量使用静态SQL执行,静态语句会自动使用绑定变量

以上语句execute immediate 是一种动态语句写法,常用语表名字段是变量的情况,由于表名不知道,需要将变量拼成SQL语句,由execute immediate调用执行插入;而在这里显然多此一举,表名确定的情况下,完全可以使用insert into t values(i);

create or replace procedure proc3

as

begin

    for i in 1 ..100000

    loop

        execute immediate

        insert into t values(i);

        commit;

    end loop;

end;

/

-------批量提交

commit命令触发LGWR将REDO BUFFER写出到日志文件中,并且将回滚段的活动事务标记为不活动,同事让回滚段中记录对应前镜像记录所在的位置标记为可以重写。切记,commit不是触发写数据动作,写数据将数据从DATA BUFFER刷出磁盘,这个过程是由CKPT进程决定的。commit操作消耗的时间不是很大,单次提价可能需要0.001秒完成。批量100万条更新提交后完成commit提交可能也就0.8秒不超过1秒。但是10万次单次提交就会消耗不少时间

create or replace procedure proc3

as

begin

    for i in 1 ..100000

    loop

        execute immediate

        insert into t values(i);

    end loop;

  commit;

end;

/

------集合写法

集合写法是改变原来的插入方式,由一条一条插入变为一整批写进到DATA BUFFER区里

insert into t select rownum from dual connect by level <= 100000;

------直接路径

修改前::

connect ljb/ljb

drop table t purge;

create table t (x int);

alter system_flush shared_pool;

set timing on

insert into t select rownum from dual connect by level <= 10000000; ---1000万条记录,执行时间00:00:23.22   23秒多

修改后:

drop table t purge;

alter system flush shared_pool;

set timing on

create table t as select rownum x from dual connected by level <= 10000000;   ----执行时间00:00:10.14

后面这种create table方式跳过了数据缓冲区,直接写到磁盘中。直接路径读写方式缺点在于由于数据不经过数据缓存区,在数据缓存区读不到这些数据,因此一定会有物理读。但是在很多时候,尤其是海量数据需要迁移插入,快速插入才是第一目的,该表一般记录巨大,DATA BUFFER甚至还装不下其十分之一、百分之一,这些共享的数据意义不大,这时,我们一般会选择直接路径读写的方式来完成海量数据的插入。

------并行设置

设置日志关闭,并且使之parallel 16表示用到机器的16个CPU,仅仅使用4秒不到的时间就完成。

drop table t purge;

alter system flush shared_pool;

set timing on

create table t  nologging parallel 16 as select rownum x from dual connected by level <= 10000000;  

并行设置会占用大多数的CPU资源,如果是一个并发环境,有很多应用在跑,会导致别的应用资源不足,导致很严重的问题,所以并发设置需要三思而后行。

 

0 0
原创粉丝点击