<div>监测表使用空间情况<br>declare</div><div> l_tabname varchar2(30) := '&1';</div><div> l_fs1_bytes number;</div><div> l_fs2_bytes number;</div><div> l_fs3_bytes number;</div><div> l_fs4_bytes number;</div><div> l_fs1_blocks number;</div><div> l_fs2_blocks number;</div><div> l_fs3_blocks number;</div><div> l_fs4_blocks number;</div><div> l_full_bytes number;</div><div> l_full_blocks number;</div><div> l_unformatted_bytes number;</div><div> l_unformatted_blocks number;</div><div>begin</div><div> dbms_space.space_usage(</div><div> segment_owner => 'HR',</div><div> segment_name => l_tabname,</div><div> segment_type => 'TABLE',</div><div> fs1_bytes => l_fs1_bytes,</div><div> fs1_blocks => l_fs1_blocks,</div><div> fs2_bytes => l_fs2_bytes,</div><div> fs2_blocks => l_fs2_blocks,</div><div> fs3_bytes => l_fs3_bytes,</div><div> fs3_blocks => l_fs3_blocks,</div><div> fs4_bytes => l_fs4_bytes,</div><div> fs4_blocks => l_fs4_blocks,</div><div> full_bytes => l_full_bytes,</div><div> full_blocks => l_full_blocks,</div><div> unformatted_bytes => l_unformatted_bytes,</div><div> unformatted_blocks => l_unformatted_blocks</div><div> );</div><div> dbms_output.put_line('0-25% Free = '||l_fs1_blocks||' Bytes = '||l_fs1_bytes);</div><div> dbms_output.put_line('25-50% Free = '||l_fs2_blocks||' Bytes = '||l_fs2_bytes);</div><div> dbms_output.put_line('50-75% Free = '||l_fs3_blocks||' Bytes = '||l_fs3_bytes);</div><div> dbms_output.put_line('75-100% Free = '||l_fs4_blocks||' Bytes = '||l_fs4_bytes);</div><div> dbms_output.put_line('Full Blocks = '||l_full_blocks||' Bytes = '||l_full_bytes);</div><div>end;</div><div><br></div>
概念
当对一个对象进行全扫描时,与该对象相关的所有数据块都必须取出并进行处理,以确定块中所包含的数据行是否是查询所需要的。
Oracle必须将整个数据块读取到内存中以取得这个块中所存储的数据行的数据。
当发生全扫描时,优化器要做两件事<br>1、必须读取多少个数据块<br>2、每个数据块中有多少数据被舍弃
如何选择全扫描操作
数据存储方式也将会影响优化器对执行计划的选择
例如,有两个表,基数都是10000行,一个表中的数据以顺序存储,另一个表中的数据是随机存储。现在获取同样的100行数据,顺序存储的表将会以索引执行,而随机存储的表则是全表扫描<br>原因:顺序存储的表中可能只需要读取几个块,而随机存储的表中需要读取所有的块
全扫描与舍弃
全扫描是否为高效的选择取决于需要访问的数据块个数以及最终的结果集行数
全扫描是否为高效选择的另一个关键因素是舍弃
访问的数据块数目以及舍弃的数量越大,全表扫描的成本也就越高
全扫描与多块读取
全表扫描将会进行多块读取,也就是说一个单独的IO调用将会请求多个块而不是仅仅一个。所请求的数据块数据是可变的,实际上可以是从1个到db_file_multiblock_read_count参数所指定的数据范围之间的任意个。
Oracle不得不读取超过一定边界范围的数据块。
如果一个数据块已经在缓冲区缓存,那么它将会作为多块读取的一部分重新读取一遍。Oracle将会只读取那些尚在内存中的数据块。
超出了操作系统限制的多块读取大小。这取决于使用操作系统,因此是可变的。
全扫描与高水位线
当对扫描进行多块读取调用时,Oracle将最多读取到位于表中高水位线的数据块。高水位线标出了表中最后一块有数据写入的数据块。
SELECT BLOCKS FROM USER_SEGMENTS WHERE SEGMENT_NAME = 'ORDERS';<br>查看某个表的高水位线对应的数据块数
SELECT COUNT(DISTINCT (DBMS_ROWID.rowid_block_number(ROWID))) BLOCK_CNT FROM ORDERS;<br>查看某个表实际使用的数据块数
读取额外的空块所带来的成本也可能严重降低性能。对于频繁加载和清除的表(使用delete而不是truncate),你可能发现响应时间会变慢。