优化Oracle库表设计的若干方法

来源:asp之家 时间:2010-07-16 13:24:00 

前言

  绝大多数的Oracle数据库性能问题都是由于数据库设计不合理造成的,只有少部分问题根植于Database Buffer、Share Pool、Redo Log Buffer等内存模块配置不合理,I/O争用,CPU争用等DBA职责范围上。所以除非是面对一个业已完成不可变更的系统,否则我们不应过多地将关注点投向内存、I/O、CPU等性能调整项目上,而应关注数据库表本身的设计是否合理,库表设计的合理性才是程序性能的真正执牛耳者。
合理的数据库设计需要考虑以下的方面:

  ·业务数据以何种方式表达。如一个员工有多个Email,你可以在T_EMPLOYEE表中建立多个Email字段如email_1、email_2、email_3,也可以创建一个T_EMAIL子表来存储,甚至可以用逗号分隔开多个Email地址存放在一个字段中。

  ·数据以何种方式物理存储。如大表的分区,表空间的合理设计等。

  ·如何建立合理的数据表索引。表索引几乎是提高数据表查询性能最有效的方法,Oracle拥有类型丰富的数据表索引类型,如何取舍选择显得特别重要。

  本文我们将目光主要聚焦于数据表的索引上,同时也将提及其他两点的内容。通过对一个简单的库表设计实例的分析引出设计中的不足,并逐一改正。考虑到手工编写库表的SQL脚本原始且低效,我们将用目前最流行的库表设计工具PowerDesigner 10来讲述表设计的过程,所以在本文中你还会了解到一些相关的PowerDesigner的使用技巧。

  一个简单的例子

  某个开发人员着手设计一个订单的系统,这个系统中有两个主要的业务表,分别是订单基本信息表和订单条目表,这两张表具有主从关系的表,其中T_ORDER是订单主表,而T_ORDER_ITEM是订单条目表。数据库设计人员的设计成果如图 1所示:


  ORDER_ID是订单号,为T_ORDER的主键,通过名为SEQ_ORDER_ID的序列产生键值,而ITEM_ID是T_ORDER_ITEM表的主键,通过名为SEQ_ORDER_ITEM的序列产生键值,T_ORDER_ITEM通过ORDER_ID外键关联到T_ORDER表。

  需求文档指出订单记录将通过以下两种方式来查询数据:

  ·CLIENT + ORDER_DATE+IS_SHPPED:根据"客户+订货日期+是否发货"条件查询订单及订单条目。

  ·ORDER_DATE+IS_SHIPPED:根据"订货日期+是否发货"条件查询订单及订单条目。

  数据库设计人员根据这个要求,在T_ORDER表的CLIENT、 ORDER_DATE及IS_SHPPED三字段上建立了一个复合索引IDX_ORDER_COMPOSITE;在T_ORDER_ITEM为外键ORDER_ID建立IDX_ORDER_ITEM_ORDER_ID索引。

  让我们看一下该份设计的最终SQL脚本:


  我们承认在ER关系上,这份设计并不存在的缺陷,但却存在以下有待优化的地方:

  ·没有将表数据和索引数据存储到不同的表空间中,而不加区别地将它们存储到同一表空间里。这样,不但会造成I/O竞争,也为数据库的维护工作带来不便。

  ·ORACLE会自动为表的主键列创建一个普通B-Tree索引,但由于这两张表的主键值都通过序列提供,具有严格的顺序性(升序或降序),此时手工为其指定一个反键索引(reverse key index)将更加合理。

  ·在子表T_ORDER_ITEM外键列ORDER_ID上建立的IDX_ORDER_ITEM_ORDER_ID的普通B-Tree索引非常适合设置为压缩型索引,即建立一个压缩型的B-Tree索引。因为一份订单会对应多个订单条目,这就意味着T_ORDER_ITEM表存在许多同值的ORDER_ID列值,通过将其索引指定为压缩型的B-Tree索引,不但可以减少IDX_ORDER_ITEM_ORDER_ID所需的存储空间,还将提高表操作的性能。

  ·企图仅通过建立一个包含3字段IDX_ORDER_COMPOSITE复合索引满足如前所述的两种查询条件方式的索引是有问题的,事实上使用ORDER_DATE+IS_SHIPPED复合条件的查询将利用不到IDX_ORDER_COMPOSITE索引。

标签:数据库优化,oracle,表
0
投稿

猜你喜欢

  • 浅析JavaScript中的array数组类型系统

    2024-04-17 10:04:21
  • 基于B-树和B+树的使用:数据搜索和数据库索引的详细介绍

    2024-01-19 01:28:16
  • 菜鸟大讲堂:如何查看mysql版本的四种方法

    2009-09-05 09:54:00
  • 微信小程序转化为uni-app项目的方法示例

    2024-03-23 19:34:39
  • 利用Python实现Windows下的鼠标键盘模拟的实例代码

    2023-06-22 04:37:31
  • python快速建立超简单的web服务器的实现方法

    2021-03-14 23:25:14
  • ASP 日期的加减运算实现代码

    2011-03-08 10:47:00
  • vue在页面中如何使用window全局变量

    2024-05-09 15:14:49
  • Oracle 查询表信息获取表字段及字段注释

    2024-01-14 14:46:36
  • mysql建立自定义函数的问题

    2024-01-19 06:26:52
  • Python实现将内容转为base64编码与解码

    2021-11-25 14:44:24
  • getWindow与isWindow

    2009-12-28 13:12:00
  • Python采用Django制作简易的知乎日报API

    2023-10-07 13:02:34
  • Mac系统下MySql下载MySQL5.7及详细安装图解

    2024-01-19 21:36:00
  • Python对口红进行数据分析来选定情人节礼物

    2022-01-23 07:38:08
  • 深入透析样式表滤镜(下)

    2011-06-14 09:49:19
  • pytorch 计算Parameter和FLOP的操作

    2023-03-01 04:15:55
  • 存储过程配合UpdateDaset方法批量插入Dataset数据实现代码

    2024-01-25 12:29:59
  • 简单谈谈CommonsChunkPlugin抽取公共模块

    2024-04-19 10:14:27
  • 日常收集整理php正则表达式(超常用)

    2024-05-03 15:35:49
  • asp之家 网络编程 m.aspxhome.com