1。使用LMT时,不更新数据字典,不产生回滚活动。
2。自动跟踪相邻的自由空间,不需要合并盘区。
3。通过更新自由块和已用块的位映射来治理空间,避免了递归的空间治理操作。
4。有UNIFORM和AUTOALLOCATE两种指定盘区大小方法,缺省为AUTOALLOCATE
5。临时表空间用LMT治理则仅仅只能用UNIFORM分配方式
6。针对LMT,NEXT, PCTINCREASE, MINEXTENTS, MAXEXTENTS, and DEFAULT STORAGE 将不再起作用
7。用UNIFORM指定一个值,表示盘区大小,缺省是1M,而对AUTOALLOCATE,你只要指定一个初始盘区的大小,Oracle会自动用一个最佳值为其他盘区指定大小,最小是64KB,这也是固定表空间中系统治理的缺省盘区大小。
这里我还不明白,这是说ORACLE为其他的盘区分配的盘区大小是不定的但最小是64Kb,不知这个理解对不对。那么初始盘区该设多大呢?最小也是64KB吧。如此说AUTOALLOCATE方式比UNIFORM方式更好吗?
盘区的分配:
ORACLE首先在第一个属于这个表空间的数据文件中分配一个新的盘区,先为需要的相邻自由块数目在这个数据文件中查找位映射(BITMAP),假如这个数据文件没有足够的自由块数目,ORACLE则查找下一个数据文件。当这个盘区释放了,ORACLE修改数据文件的位映射。
位映射治理:
假设指定的一个盘区大小是256KB,一个数据块的大小是4KB,则
256/4=64,表示位映射中的每一位都表示64块。
我的环境是WIN2000+ORACLE817, db_block_size=4096
问题一:理解BITMAP治理
1。首先建立表空间
SYS@ORAEXP:ADMIN> create tablespace abc datafile 'd:\oracle817\oradata\oraexp\abc.dbf' size
21000k extent management local uniform size 40k;
2.立即查看DBA_FREE_SPACE
SYS@ORAEXP:ADMIN> select * from dba_free_space where tablespace_name='ABC';
TABLESPACE_NAMEFILE_ID BLOCK_IDBYTES BLOCKS
------------------------------ ---------- ---------- ---------- ----------
RELATIVE_FNO
------------
ABC15 17942080230
15
这里看到block_id=17,说明已经使用了16块,这16块就是给这个数据文件分配的BITMAP使用的,16*4=64KB,
另外,我们建立这个表空间是1000KB,也就是250块,但现在只有230块,加上已用的16块,也只有246块,还有8块到哪里去了?因为一个盘区是40/4=10个块,8个块还不能构成一个盘区,所以被浪费了。这就是为什么上面说的在建立表空间数据文件是要在数据文件大小上再加上64K的原因了。
再看看效果:
SYS@ORAEXP:ADMIN> create tablespace abc_1 datafile 'd:\oracle817\oradata\oraexp\abc_1.dbf'
2size 1064k extent management local uniform size 40k;
SYS@ORAEXP:ADMIN> select * from dba_free_space where tablespace_name='ABC_1';
TABLESPACE_NAMEFILE_ID BLOCK_IDBYTES BLOCKS
------------------------------ ---------- ---------- ---------- ----------
RELATIVE_FNO
------------
ABC_1 16 171024000250
16
只要加上64K,就能救回很多空间来!!!
问题2:盘区的分配:
建立一张表:
SYS@ORAEXP:ADMIN> CREATE TABLE ABC(A VARCHAR2(10)) TABLESPACE ABC STORAGE
2(INITIAL 20K NEXT 20K );
SYS@ORAEXP:ADMIN> SELECT* FROM DBA_FREE_SPACE WHERE TABLESPACE_NAME='ABC';
TABLESPACE_NAME FILE_ID BLOCK_IDBYTES BLOCKS
------------------------------ ---------- ---------- ---------- ----------
RELATIVE_FNO
------------
ABC15 27 901120220
15
可见并没有按照建表定义里的参数INITIAL来分配表空间,而是按照定义的UNIFORM SIZE来分配盘区的。
假如定义INITIAL参数大于UNIFORM SIZE 定义呢?
先DROP 表 ABC恢复到表空间ABC初始定义的状态。
再重建表ABC
SYS@ORAEXP:ADMIN> CREATE TABLE ABC(A VARCHAR2(10)) TABLESPACE ABC STORAGE
2(INITIAL 100K NEXT 100K);
SYS@ORAEXP:ADMIN> SELECT * FROM DBA_FREE_SPACE WHERE TABLESPACE_NAME='ABC';
TABLESPACE_NAME FILE_ID BLOCK_IDBYTES BLOCKS
------------------------------ ---------- ---------- ---------- ----------
RELATIVE_FNO
------------
ABC15 47 819200200
15
分配30块,也就是120KB,因为建表是定义INITIAL是100KB,按照UNIFORM SIZE 40K 只能分配120KB才能满足。
再让表扩展一个盘区
SYS@ORAEXP:ADMIN> ALTER TABLE ABC ALLOCATE EXTENT;
表已更改。
SYS@ORAEXP:ADMIN> SELECT * FROM DBA_FREE_SPACE WHERE TABLESPACE_NAME='ABC';
TABLESPACE_NAME FILE_ID BLOCK_IDBYTES BLOCKS
------------------------------ ---------- ---------- ---------- ----------
RELATIVE_FNO
------------
ABC 15 57 778240190
15
看出只用了10块,也就是40KB,还是按照UNIFORM SIZE 40K分配的,并没有使用建表里NEXT 100KB参数。
SYS@ORAEXP:ADMIN> L
1SELECT INITIAL_extent,next_extent,min_extentS,max_extentS from dba_segmentS
2* where segment_name='ABC'
SYS@ORAEXP:ADMIN> /
INITIAL_EXTENT NEXT_EXTENT MIN_EXTENTS MAX_EXTENTS
-------------- ----------- ----------- -----------
102400 40960 12147483645
这里就可以看到ABC表的初始盘区是100KB,具体盘区分配:
SYS@ORAEXP:ADMIN> select extent_id,file_id,block_id,bytes,blocks from
2dba_extents where segment_name='ABC';
EXTENT_IDFILE_ID BLOCK_IDBYTES BLOCKS
---------- ---------- ---------- ---------- ----------
0 15 1740960 10
1 15 2740960 10
2 15 3740960 10
3 15 4740960 10
得到结论:
1。建LMT表空间时,考虑在建立的数据文件大小上再加64KB
2。对于LMT表空间,建表STORAGE里的参数基本没什么用处了,仅仅是在第一次分配时参考INITIAL和NEXT参数分配空间,实际还是按照UNIFORM SIZE来分配盘区。EXP/IMP时应该避免使用COMPRESS=Y参数,否则初始盘区会很大的。
要做到准确的性能测试,其实是很复杂的。
一般而言,虽然LMT的表空间不会比DICT的表空间性能上强很多,但是不会更差 的。
你要做性能的对比测试,应该给他们完全相等的条件。
比如,你第一次已经做了测试,做了大量的数据插入,但是在第二次做测试的时候,可能就会出现ckpt 不能完成的情况。这样一来,第二次的性能数据肯定会大大打折扣的。
至于空间治理,我现在的,基本上都采用了LMT + Uniform 的大小,按照表的增长和大
小来划分不同的表空间。
基本上不再区分索引和表了。