表的存储参数Freelist(自由列表)对性能的影响

今天演示一下表的存储参数Freelist(自由列表)对性能的影响
我们知道,在对表进行大数据量的插入和更新时,配置多个Freelist能提高整体性能,然而配置多个Freelist有可能浪费更多的空间,一定要找出并行
插入和更新的最大数,
下面例子说明这点
我们创建一个表
SQL> conn hr/hr123
已连接。
SQL> drop table t;

表已删除。

SQL> create table t (x int );
创建一个临时表,用来存放v$waitstat表中的数据
SQL> create  global temporary table waitstat_before
  2  on commit preserve rows   (表示会话中止时或者导常退出时数据都会被清除掉)
  3  as
  4  select * from v$waitstat
  5  where 1=0;

表已创建。

SQL> select * from waitstat_before;

未选定行

SQL> insert into waitstat_before
  2  select * from v$waitstat;

已创建18行。
下面我们开始两个会话往T表同时插入数据
SQL> ed
已写入 file afiedt.buf

  1  begin
  2 for i in 1 .. 100000
  3 loop
  4   insert into t values (i);
  5   commit;
  6 end loop;
  7* end;
SQL> /

PL/SQL 过程已成功完成。
另一个会话也同时执行
SQL> ed
已写入 file afiedt.buf

  1  begin
  2 for i in 1 .. 100000
  3 loop
  4   insert into t values (i);
  5   commit;
  6 end loop;
  7* end;
SQL> /

PL/SQL 过程已成功完成。

我们查询表
select a.class ,b.count-a.count count , b.time-a.time time
from hr.waitstat_before a ,v$waitstat b
where a.class = b.class;
执行入下结果:

SQL> select a.class ,b.count-a.count count , b.time-a.time time
  2  from waitstat_before a ,v$waitstat b
  3  where a.class = b.class;

CLASS   COUNT     TIME
------------------ ---------- ----------
data block    860     2541
sort block      0        0
save undo block      0        0
segment header      1        2
save undo header     0        0
free list      0        0
extent map      0        0
1st level bmb      0        0
2nd level bmb      0        0
3rd level bmb      0        0
bitmap block      0        0

CLASS   COUNT     TIME
------------------ ---------- ----------
bitmap index block     0        0
file header block     0        0
unused       0        0
system undo header     0        0
system undo block     0        0
undo header    181       58
undo block      0        0

已选择18行。

SQL>
我们看到,当这些会话并行运行时,等待超过25秒,这完全是由于在表t中没有为并行任务配置足够的Freelist,下面改变Freelist的大小
SQL> alter table t storage(freelists 3);
alter table t storage(freelists 3)
*
第 1 行出现错误:
ORA-10620: Operation not allowed on this segment
这是由于oracle11g默认为自动段空间管理,在这种模式下,Oracle不能修改表的存储参数

select tablespace_name,extent_management,segment_space_management from dba_tablespaces where tablespace_name='EXAMPLE';

TABLESPACE_NAME         EXTENT_MAN SEGMEN
------------------------------ ---------- ------
EXAMPLE          LOCAL   AUTO
下面我们创建一个手动段空间管理的表空间
SQL> create tablespace manual_tbs
  2  datafile '/u01/app/oracle/oradata/R2/manual_tbs01.dbf' size 100M
  3  extent management local
  4  segment space management manual;

表空间已创建。
SQL> create user dm identified by dm default tablespace manual_tbs;

用户已创建。

SQL> conn dm/dm
ERROR:
ORA-01045: 用户 DM 没有 CREATE SESSION 权限; 登录被拒绝

授权dba角色给dm用户

SQL> conn / as sysdba
已连接。
SQL> grant dba to dm;

授权成功。

SQL> conn dm/dm
已连接。
SQL> create table t (x int);

表已创建。

SQL> alter table t storage (freelists 2);

表已更改。

SQL> truncate table hr.waitstat_before;

表被截断。
SQL> ed
已写入 file afiedt.buf

  1  insert into hr.waitstat_before
  2* select * from v$waitstat
SQL> /

已创建18行

SQL> ed
已写入 file afiedt.buf

  1  begin
  2    for i in 1 .. 100000
  3    loop
  4  insert into t values (i);
  5  commit;
  6    end loop;
  7* end;
SQL> /

PL/SQL 过程已成功完成。

SQL>
我们再次查询
SQL> select a.class ,b.count-a.count count , b.time-a.time time
from hr.waitstat_before a ,v$waitstat b
  2  where a.class = b.class;
  3 
CLASS   COUNT     TIME
------------------ ---------- ----------
data block      0        0
sort block      0        0
save undo block      0        0
segment header      0        0
save undo header     0        0
free list      0        0
extent map      0        0
1st level bmb      0        0
2nd level bmb      0        0
3rd level bmb      0        0
bitmap block      0        0

CLASS   COUNT     TIME
------------------ ---------- ----------
bitmap index block     0        0
file header block     0        0
unused       0        0
system undo header     0        0
system undo block     0        0
undo header      2        0
undo block      0        0

已选择18行。
等待时间已经消除
可见,freelists存储参数对大数据量的插入和更新的性能有很大影响。那么我们在做批量数据操作的时候,可以临时改变表的存储参数,可以很好的提高数据库的性能,不过在Oracle10g以后,默认表空间的管理方式为自动。要想修改表的存储参数,表空间必须为手动段空间管理。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/7551038/viewspace-617045/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/7551038/viewspace-617045/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
freelist是一个用于管理内存的数据结构,它是一种空闲链,用于存储已经被释放的内存块,以便下次使用时可以直接从freelist中取出。 以下是一个简单的freelist实现方法: 1. 定义一个结构体来示内存块,包含两个成员变量:指向下一个内存块的指针和内存块的大小。 2. 定义一个全局的指针变量,指向freelist的头部。 3. 当需要释放一块内存时,将其加入到freelist中,即将该内存块的指针指向当前freelist的头部,并将freelist的头部指针指向该内存块。 4. 当需要分配一块内存时,从freelist中取出一块内存,即将当前freelist的头部指针指向下一个内存块,并返回该内存块的指针。 5. 如果freelist中没有足够的内存块,则向操作系统请求更多的内存。 以下是一个示例代码: ``` #include <stdlib.h> // 内存块结构体 struct block { struct block* next; // 指向下一个内存块 size_t size; // 内存块大小 }; // freelist头部指针 struct block* freelist = NULL; // 分配内存 void* allocate(size_t size) { // 检查freelist中是否有足够的内存块 if (freelist == NULL || freelist->size < size) { // 向操作系统请求更多的内存 return malloc(size); } // 从freelist中取出一块内存 struct block* block = freelist; freelist = freelist->next; return block + 1; } // 释放内存 void deallocate(void* ptr) { // 将内存块加入到freelist中 struct block* block = (struct block*)ptr - 1; block->next = freelist; freelist = block; } ``` 注意,这只是一个简单的freelist实现方法,实际应用中可能需要进行优化和改进。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值