3.2 基本表设计优化
在基于表驱动的信息管理系统中,基本表的设计规范是第三范式。第三范式的基本特征 是非主键属性只依赖于主键属性。基于第三范式的数据库表设计具有很多优点:一是能消除 冗余数据、节省磁盘存储空间;二是有良好的数据完整性限制(基于主外键的参照完整限制 和基于主键的实体完整性限制),这使得数据容易维护、移植和更新;三是数据的可逆性好, 在做连接查询或者合并表时不遗漏、不重复;四是消除了冗余数据(这里主要指冗余列), 使得查询时每个数据页存储的数据行增多,这样就有效地减少了逻辑I/O,同时也减少了物 理I/O;五是对大多数事务而言,运行性能好;六是物理设计的机动性较大,能满足日益增 长的用户需求。
基于第三范式设计的库表虽然有其优越性,然而在实际应用中有时不利于系统运行性能 的优化:例如需要部分数据时而要扫描整表,许多过程同时竞争同一数据,反复用相同行计 算相同的结果,过程从多表获取数据时引发大量的连接操作,当数据来源于多表时的连接操 作;这都消耗了磁盘I/O 和CPU 时间。特别需要提出的是,在遇到下述情形时,我们要对 基本表进行扩展设计优化:许多过程要频繁访问一个表、子集数据访问、重复计算和冗余数 据,有时用户要求一些过程优先或低的响应时间,为避免以上不利因素,我们通常根据访问 的频繁程度对相关表进行分割处理、存储冗余数据、存储衍生列、合并相关表处理,这些都 是克服这些不利因素和优化系统运行的有效途径。
(1)分割表 分割表可分为水平分割表和垂直分割表两种:水平分割是按照行将一个表分割为多个 表,这可以提高每个表的查询速度,但是由于造成了多表连接,所以应该在同时查询或更新 不同分割表中的列的情况比较少的情况下使用。垂直分割是对于一个列很多的表,若某些列 的访问频率远远高于其它列,在不破坏第三范式的前提下将主键和这些列作为一个表,将主 键和其它列作为另外一个表。一种是当多个过程频繁访问表的不同列时,可将表垂直分成几 个表,减少磁盘I/O。通过减少列的宽度,增加了每个数据页的行数,一次I/O 就可以扫描 更多的行,从而提高了访问每一个表的速度。垂直分割表可以达到最大化利用Cache 的目的。 分割表的缺点是要在插入或删除数据时要考虑数据的完整性,用存储过程维护。
(2)存储衍生数据 对一些要做大量重复性计算的过程而言,若重复计算过程得到的结果相同,或计算牵扯 多行数据需额外的磁盘I/O 开销,或计算复杂需要大量的C P U 时间,就考虑存储计算结果:若在一行或多行进行重复性计算,就在表内增加列存储结果,但若参与计算的列被更新时, 必须要用触发器或存储过程更新这个新列。总之,存储冗余数据有利于加快访问速度,但违 反了第三范式,这会增加维护数据完整性的代价,必须用触发器立即更新、或存储过程更新, 以维护数据的完整性。
3.3 修改应用技术模式
引入“中间表”的概念,在实际单据未进入核心业务流程前,采用“中间表”的技术思 路,就是在实际用户操作过程中,实际操作的是一个临时表,在进行数据某个阶段审核(进 入下一个环节)后,将临时表的数据写入正式表,并且删除临时表的数据,这样始终保持用 户操作表的固定的数据量而且控制增长,可以定期清除。 采用临时表技术首先需将要操作的数据集插入到临时表中,这会给系统带来额外的开 销。这里假设临时表中的数据集远小于源数据表中的数据集,因此在进行数据连接操作或对 数据集进行频繁读操作时,系统的性能会提高几倍甚至几十倍不等。
并非所有情况都适宜用临时表技术。一般来说,下面两种情况适宜采用临时表技术进行 处理:
(1)对数据量较大的表进行连接操作,并且连接操作的结果是一个小结果集。
(2)对数据量较大的表进行频繁访问,访问的范围比较固定且比较集中。
合理使用临时表技术,有助于提高应用系统对大数据表的实时处理的性能。
4.数据库索引优化
索引是建立在表上的一种数据组织,它能提高访问表中一条或多条记录的特定查询效 率。利用索引优化系统性能是显而易见的,对所有常用于查询中的Where 子句的列和所有 用于排序的列创建索引,可以避免整表扫描或访问,在不改变表的物理结构的情况下,直接 访问特定的数据列,这样可以减少数据存取时间;利用索引可以优化或排除耗时的分类操作, 把数据分散到不同的页面上,这样就分散了插入的数据;主键自动建立了唯一索引,因此唯 一索引也能确保数据的唯一性(即实体完整性)。总之,索引可以加快查询速度、减少I/O 操作、消除磁盘排序。 优化索引可以避免扫描整个表,减少因查询造成的开销。一般说来建立索引要注意以下 几点:
(1)检查被索引的列或组合索引的首列是否出现在PL/SQL 语句的WHERE 子句中, 这是“执行计划”能用到相关索引的必要条件。比较一下列中唯一键的数量和表中记录的行 数,就可以判断该列的可选择性。如果该列的“唯一键的数量/表中记录行数”的比值越接近 于1,则该列的可选择行越高。在可选择性高的列上进行查询,返回的数据就较少,比较适 合索引查询。相反,比如性别列上只有两个值,可选择行就很小,不适合索引查询。因此, 在查询中经常作为条件表达式且不同值较多的列上建立索引,不同值较少的列上不要建立索 引。
(2)索引的创建也是需要代价的,对于删除、某些更新、插入操作,对于每个索引都 要进行相应的删除、更新、插入操作。从而导致删除、某些更新、插入操作的效率变低。因 此频繁进行删除、插入操作的表不要建立过多的索引。
(3)查询经常用到的列上建立非聚簇索引,在频繁进行范围查询、排序、分组的列上 建立聚簇索引。
(4 )对于不存在重复值的列,创建唯一索引优于创建非唯一索引。
(5)当数据库表更新大数据后,删除并重新建立索引来提高查询速度。
(6)当对一个表的update 操作远远多于select 操作时,不应创建索引。
(7)如果索引列是函数的参数,则索引在查询时用不上,该列也不适合索引。