设为首页 收藏本站
查看: 1039|回复: 0

[经验分享] 通过案例学调优之--Oracle数据块(block)

[复制链接]

尚未签到

发表于 2018-9-11 10:01:45 | 显示全部楼层 |阅读模式
  通过案例学调优之--Oracle数据块(data block)

  数据块概述Oracle对数据库数据文件(datafile)中的存储空间进行管理的单位是数据块(data block)。数据块是数据库中最小的(逻辑)数据单位。与数据块对应的,所有数据在操作系统级的最小物理存储单位是字节(byte)。每种操作系统都有一个被称为块容量(block>
  数据库中标准的数据块(data block)容量是由初始化参数 DB_BLOCK_SIZE 指定的。除此之外,用户还可以指定五个非标准的数据块容量(nonstandard block>
  另见:针对特定操作系统的Oracle文档中包含更多有关数据块容量(data block>  数据块结构在Oracle中,不论数据块中存储的是表(table)、索引(index)或簇表(clustered data),其内部结构都是类似的。
DSC0000.gif

  本图显示了数据块的各个组成部分,包括:数据块头(包括标准内容和可变内容)(common and variable header),表目录区(table directory),行目录区(row directory),可用空间区(free space),行数据区(row data)。以下各节将分别讲解各个组成部分。图中两个箭头表示一个数据块中的可用空间区的容量是可变的。
  数据块头(包括标准内容和可变内容)
  数据块头(header)中包含了此数据块的概要信息,例如块地址(block address)及此数据块所属的段(segment)的类型(例如,表或索引)。
  表目录区
  如果一个数据表在此数据块中储存了数据行,那么数据表的信息将被记录在数据块的表目录区(table directory)中。
  行目录区
  此区域包含数据块中存储的数据行的信息(每个数据行片断(row piece) 在行数据区(row data area)中的地址)。[一个数据块中可能保存一个完整的数据行,也可能只保存数据行的一部分 ,所以文中使用row piece]
  当一个数据块(data block)的行目录区(row directory)空间被使用后,即使数据行被删除(delete),行目录区空间也不会被回收。举例来说,当一个曾经包含50条记录的数据块被清空后,其块头(header)的行目录区仍然占用100字节(byte)的空间。只有在数据块中插入(insert)新数据时,行目录区空间才会被 重新利用。
  管理开销数据块头(data block header),表目录区(table directory),行目录区(row directory)被统称为管理开销(overhead)。其中 有些开销的容量是固定的;而有些开销的总容量是可变的。数据块中固定及可变管理开销的容量平均在84到107字节(byte)之间。
  行数据数据块(data block)中行数据区(row data)包含了表或索引的实际数据。一个数据行可以跨多个数据块。这就出现了“行链接(Row Chaining)及行迁移(Row Migrating)
  可用空间区在插入新数据行,或在更新数据行需要更多空间时(例如,原来某行最后一个字段为空(trailing null),现在要更新为非空值),将 使用可用空间区(free space)中的空间。
  如果一个数据块(data block)属于表或簇表的数据段(data segment),或属于索引的索引段(index segment),那么在其可用空间区中还可能会存储事务条目(transaction entry)。如果一个数据块中的数据行(row)正在由 INSERT,UPDATE,DELETE,及 SELECT……FOR UPDATE 语句访问,此数据块中就需要保存事务条目。事务条目所需的存储空间依据操作系统而定。在常见的操作系统中事务条目大约需要有两种SQL语句可以增加数据块中的可用空间:分别是 DELETE 语句,和将现有数据值更新为占用容量更小值的 UPDATE 语句。在以下两种条件下,上述两中操作释放的空间可以被后续的 INSERT 语句使用:
  如果 INSERT 语句与上述两种操作在同一事务(transaction)中,且位于释放空间的语句之后,那么 INSERT 语句可以使用被释放的空间。
  如果 INSERT 语句与释放空间的语句在不同的事务中(比如两者是由不同的用户提交的),那么只有在释放空间的语句提交后,且插入数据必需使用此数据块时,INSERT 语句才会使用被释放的空间。
  数据块(data block)中被释放出的空间未必与可用空间区(free space)相连续。Oracle在满足以下条件时才会将释放的空间合并到可用空间区:(1)INSERT 或 UPDATE 语句选中了一个有足够可用空间容纳新数据的数据块,(2)但是此块中的可用空间不连续,数据无法被写入到数据块中连续的空间里。Oracle只在 满足上述条件时才对数据块中的可用空间进行合并,这样做是为了避免过于频繁的空间合并工作影响数据库性能。
  案例1:验证Oracle data block可用空间存储的最大行数
  1)块最大可用空间
  10:52:11 SYS@ prod >SELECT kvisval,kvistag,kvisdsc from sys.x$kvis;
  no rows selected
  一般8k的块,可用空间在8096字节;一般一行记录最小长度在11字节(加上开销),所以8k的块最多可以存储8096/11=736行。
创建Dictionary管理的tablespace:  
11:21:46 SYS@ test1 >select tablespace_name,extent_management from dba_tablespaces;
  
TABLESPACE_NAME                EXTENT_MAN
  
------------------------------ ----------
  
SYSTEM                         DICTIONARY
  
SYSAUX                         LOCAL
  
UNDOTBS1                   LOCAL
  
TEMP1                          LOCAL
  
DICT1                          DICTIONARY
  

  
创建table(pctfree=0):
  
11:21:55 scott@ test1 >create table t3
  
pctfree 0
  
tablespace dict1
  
as
  
select * from t1;
  

  
查看数据块上的记录的行数:
  
11:33:40 SCOTT@ test1 >select object_name,object_id from user_objects
  
11:33:55   2   where object_name='T3';
  
OBJECT_NAME                     OBJECT_ID
  
------------------------------ ----------
  
T3                                  16775
  
11:33:08 SYS@ test1 >SELECT SPARE1 FROM TAB$ where obj#=16775;
  
    SPARE1
  
----------
  
       736
  案例2:验证每个块存储的行数
创建数据:  
10:31:30 SCOTT@ prod >begin
  
for i in 1..10 loop
  
  insert into emp1 select * from emp1;
  
  end loop;
  
end;
  
/
  

  
10:31:38 SCOTT@ prod >select count(*) from emp1;
  
  COUNT(*)
  
----------
  
     14336
  

  
查看表存储结构:
  
10:32:13 SCOTT@ prod >analyze table emp1 compute statistics;
  
Table analyzed.
  

  
10:33:14 SCOTT@ prod >select table_name,num_rows,blocks,empty_blocks from user_tables
  
10:33:40   2   where table_name='EMP1';
  
TABLE_NAME                       NUM_ROWS     BLOCKS EMPTY_BLOCKS
  
------------------------------ ---------- ---------- ------------
  
EMP1                                14336         91            5
  

  
查看每个数据块存储的行数:
  
10:31:59 SCOTT@ prod >SELECT rid, COUNT (rnum) rnum
  
10:32:13   2  FROM (SELECT SUBSTR (ROWID, 1, 15)  rid, ROWID rnum FROM emp1)
  
10:32:13   3  GROUP BY rid;
  
RID                                  RNUM
  
------------------------------ ----------
  
AAASa0AAEAAAAIL                        14
  
AAASa0AAEAAAAJN                       170
  
AAASa0AAEAAAAJZ                       170
  
AAASa0AAEAAAAJe                       170
  
......
  
RNUM                                  RID
  
------------------------------ ----------
  
AAASa0AAGAAAACv                       170
  
86 rows selected.
  案例3:和数据块访问有关的参数
  arraysize 参数
  arraysize定义了一次返回到客户端的行数,当扫描了arraysize 行后,停止扫描,返回数据,然后继续扫描。
  这个过程就是统计信息中的SQL*Net roundtrips to/from client。因为arraysize 默认是15行,那么就有一个问题,因为我们一个block 中的记录数一般都会超过15行,所以如果按照15行扫描一次,那么每次扫描要多扫描一个数据块,一个数据块也可能就会重复扫描多次。
  重复的扫描会增加consistent gets 和 physical reads。 增加physical reads,这个很好理解,扫描的越多,物理的可能性就越大。
  consistent gets,这个是从undo里读的数量,Oracle 为了保证数据的一致性,当一个查询很长,在查询之后,数据块被修改,还未提交,再次查询时候,Oracle根据Undo 来构建CR块,这个CR块,可以理解成数据块在之前某个时间的状态。 这样通过查询出来的数据就是一致的。
  那么如果重复扫描的块越多,需要构建的CR块就会越多,这样读Undo 的机会就会越多,consistent gets 就会越多。
  如果数据每次传到客户端有中断,那么这些数据会重新扫描,这样也就增加逻辑读,所以调整arraysize可以减少传的次数,减少逻辑读。
  默认的arraysize:
11:56:18 SCOTT@ prod >show arraysize  
arraysize 15
  

  
理论上arraysize为15,读取170行应该是12次。
  
12:13:57 SCOTT@ prod >select 170/15 from dual;
  

  
    170/15
  
----------
  
11.3333333
  

  
12:05:07 SCOTT@ prod >select * from emp1 where rownumshow arraysize
  
arraysize 1000
  

  
12:07:40 SCOTT@ prod >set autotrace trace
  
12:07:48 SCOTT@ prod >select * from emp1 where rownum

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.iyunv.com/thread-571831-1-1.html 上篇帖子: Oracle数据链创建及使用 下篇帖子: oracle session NLS_LANGUAGE
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表