数据库

位置:IT落伍者 >> 数据库 >> 浏览文章

不让链化现象影响数据库性能


发布日期:2020年02月10日
 
不让链化现象影响数据库性能

正常情况下往表中新建记录时数据库系统会将数据写入到块并会像这行记录提供一个ROWID值这个值记录了这条记录在硬盘上存储的位置在更新某 条记录的时候也是如此数据库系统会根据ROWID的值将需要更新的记录从硬盘中读取到块中;然后更新完毕后再将块中的记录保存到硬盘对应的位置更 新过程中ROWID列的值通常情况下不会改变

但是如果一个块的容量不能够容纳一条记录也就是会所当单个数据块没有足够的空间来保存新建的一行记录或者更新的某行记录时就会发生链化现象 到一个数据库的容量不足以容纳一条记录时那么数据库就不得不动用更多的数据块来保存这条记录在Oracle数据库中如果某条记录需要利用多个数据库 来保存我们往往把这行记录叫做链化行而在访问一行记录时如果需要访问多个数据块则会比访问单个数据块需要耗费更多的服务器资源会大大降低数据库 性能我们把这种因为链化行而导致的数据库性能下降的现象叫做链化现象根据专家统计严重的话链化现象可能降低数据库%的性能甚至更多所以数 据库管理员如果在数据库部署中能够有效避免链化现象那么就可以在很大程度上提升数据库的性能

如何判断是否有链化现象的存在?

那么数据库管理员该如何判断数据库中是否有链化现象的存在呢?如果没有工具光凭数据库管理员的眼力或者经验的话是很难判断的数据库管理员必须 找一个顺手的工具其实Oracle数据库设计这已经预计到这个问题对于数据库性能的不利影响为此在数据库中已经提供了追蹤分析链化现象的工具在 Oracle数据库安装主目录的/rdbms/admin下有一个脚本文件名字叫做utlchainsql这是Oracle数据库自带的一个脚本文 件我们可以利用文本编辑器等工具来打开这个脚本文件可以看到这个脚本文件主要是用来创建一个表用来保存分析脚本现象所需要的内容

第一步创建所需要的表

首先数据库管理元需要执行Oracle数据库提供的utlchainsql脚本文件这个文件位于Oracle主目录下的/rdbms /admin下这个脚本主要的用途就是建立一个表格这个表格很有用数据库系统会把分析的结果保存到这个表中默认情况下这个表格在安装数据库时并 不会自动生成如果数据库管理员需要分析数据库中是否存在链化现象那么就需要手工执行这个脚本文件以建立这张表格这张表格中主要有表名 HEAD_ROWID列等等

第二步分析目的表格

创建上面的表格后默认情况下里面是没有数据的因为还没有进行相关的分析假设现在在数据库中有一个Product的表格主要用来保存产品信 息现在数据库管理员想要知道数据库系统在操作这张表格数据的时候是否存在有链化现象此时数据库管理员就需要利用下面的语句来进行分析查询

Analyze table product list chained rows;

上面这条语句的作用就是会分析product这张表格判断这张表格中的记录是否存在在不同的块中如果这个product表格中有记录存储在 不同的块中则这条语句就会把相关的结果保存到刚才建立的表中所以如果数据库管理员查询刚才建立的表chained_rows如果这个表中有相关记 录的话则就说明数据库中存在链化现象数据库管理员需要采取相应的措施来避免这种情况如果没有的话最好

不过在使用这个语句的时候需要注意几点一是每次分析完治后最好把这个表个中的记录删除因为下次分析的时候如果表中有记录的话系统不会自 动删除所以在分析另外一个表的时候如果也有链化现象那么此时相关的记录就会很多数据库管理员阅读的时候会出现故障二是这个分析的频率最好频繁一 点当数据库中的记录比较多时或者数据更新比较频繁的情况下最好能够每隔几天就执行一下这个分析语句以判断是否有链化现象的存在等到大量记录或者表 格有链化现象的时候处理起来就会比较困难了所以对于大部分事务型的数据库系统数据库管理员要养成一个周期性分析的习惯对于大部分的数据库优化作业 来说事先追蹤远远比时候解决要重要的多当问题出现后再去解决的话往往会大费周章有些即使采取有效的措施也指能够避免后续的操作不会出现这种情 况要解决以前的记录问题只有重新导出导入数据后才能够彻底解决显然这会增加工作量与数据风险为此笔者再不厌其烦的强调一次对于这个链化现象的 追蹤分析最好能够每个星期执行一次特殊情况下还可以利用任务计划每天执行一次尽早发现问题并采取有效措施来避免这种情况

如何避免链化现象?

当数据库发现有链化现象时就需要及时调整相关设置来避免这种情况造成链化现象的主要原因是由于块的大小设置不合适所造成的如果一个数据块的 大小不能够容纳一条记录那么就容易造成链化现象所以如果适当调整数据块的大小能够在很大程度上避免这个链化现象在Oracle数据库中为了有效 避免链化现象可以通过调整参数PCTFREE来实现这个参数的主要用途就是为更新一个块所保留的空间有时候系统默认的值往往不能够满足需求为此需 要数据库管理员根据实际需要设置合适的值值得注意的是这个值可以根据表来进行设置为此如果数据库管理员认为某张表的记录可能比较长需要占用比较大 的空间时则可以针对这张表设置比较大的块

虽然通过调整PCTFREE参数可以有效避免链化现象但是有时候表设计不当也是造成这个问题的主要原因之一如有一张表M_PRODUCT表格 用来存放产品信息在这张表中其产品信息主要分为成品与原材料两类其中原材料这类产品中在系统中需要记录详细的产品规格信息而且还需要同时记录中 英文内容所以光这个产品规格中英文加起来最多的就有个左右的字符而成品信息的话相对来说比较简单此时这个表中的记录就存在着两极分化的现 象有些记录的容量很大需要利用多个数据块来进行保存就发生了链化现象而有些记录的话容量不是很大此时虽然可以通过给这个表设置比较大的数据块 来解决这个链化现象;但是同时也会浪费数据空间因为还有大部分记录的话根本用不到这么大的块空间所以在这种情况下片面调整PCTFREE参数会 降低硬盘空间的利用率此时笔者认为最好能够调整数据库表格的设计如可以将产品规格字段保存在另外一个表格中然后通过关键字连接到Product表 格中如此的话在Product表格中所有记录的的长度都会差不多此时再根据需要来调整PCTFREE参数不仅可以有效避免链化现象而且还同时 提高了硬盘空间的利用率当然对于新建立的表格需要适当的提高PCTFREE参数避免其出现链化现象不过这个基表的调整对于已经投入使用的数据 库系统来说调整的动作有点大会影响用户的正常使用为此在数据库设计的时候就需要跟用户充分的沟通在数据库初始化设计时就能够预见到这种情况 所以笔者一直强调数据库优化一定要做在前

另外如果数据库中的记录很少更新如一些决策分析系统或者数据仓库其只有在刚开始的时候需要大量的导入数据导入数据后对数据库中的内容基本上 不会再更新此时不需要把PCTFREE参数设置的太大可以设置比较小的值能够提高硬盘空间的利用率让表空间存储更多的记录可见PCTFREE 参数的大小没有一个固定的参考标准其主要根据数据库的用途表中记录的更新程度记录的大小等等决定的如何确定一个合理的PCTFREE参数值以减 少链化现象同时提高表空间的利用率这也正是数据库优化的难点与挑战所在

上一篇:Oracle PRKC-1002错误原因和解决方案

下一篇:oracle数据库中关于游标的常见用法