oracle数据库表优化设计的几种方法
前言
大多数的Oracle数据库,因为数据库的性能问题是由设计不合理造成的,只有一小部分的问题是根植于数据库缓冲区、共享池、重做日志缓冲区的内存模块配置不合理,争我 / O,争夺上CPU和DBA的职责范围。所以除非一个完整的系统,面对无法改变的,否则我们不应该过分注重记忆,我 / O、CPU等性能的调整项目,并应注意数据库表本身的设计是否合理,合理的数据库设计是程序性能的真正主宰的领域。
合理的数据库设计需要考虑以下几个方面:
业务数据的表达方式。如果一个员工有多个邮件,你可以在t_employee表创建多个邮件域,如email_1,email_2和email_3,或创建一个t_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是相关联的t_order order_id表通过外键。
需求文档指出,订单记录将以以下两种方式查询数据:
客户端+ order_date + is_shpped:查询订单和订单根据客户+订单日期交货条件进入。
order_date + is_shipped:查询订单和订单根据订单+配送条件的日期生效。
基于这种需求,数据库设计人员建立一个综合指数idx_order_composite在客户端,order_date和is_shpped t_order表的三个字段,并设置idx_order_item_order_id指数t_order_item外键order_id。
让我们看看这个设计的最后SQL脚本:
我们认识到ER关系中不存在设计,但有以下方面需要优化:
表数据和索引数据不存储在不同的表空间中,它们被随意地存储在同一个表空间中,这样不仅造成I/O竞争,而且给数据库的维护工作带来不便。
Oracle会自动为表的主键的列创建一个简单的B树索引,但由于两个表的主键值的序列,具有严格的顺序(升序或降序),然后手动分配一个反向键索引(反向键索引)将更加合理。
对idx_order_item_order_id建在子表的外键列t_order_item order_id常见的B树索引是设置压缩指数很合适,那就是建立一个压缩的B树索引,因为订单会对应多个订单项,这意味着t_order_item表具有许多相同的价值order_id列值,为B树索引的压缩类型指定的指标,不仅可以减少所需的idx_order_item_order_id存储空间,也提高了工作台的性能。
并尝试只通过一个idx_order_composite复合索引建立在指数是一个问题的3个领域如遇到两种查询条件,使用order_date + is_shipped复合条件。事实上,查询将不使用idx_order_composite指数。
{分页}
优化设计
1。从表数据和索引数据中分离表空间
为什么1.1个表数据和索引需要使用独立的表空间
甲骨文已牢固建立。任何应用程序库表至少需要两个表空间的创建,其中一个是存储表数据,而另一个存储表的索引数据。因为如果将表数据和索引数据,我 / O操作表数据和我/索引操作将产生我 / O的竞争,会影响系统的性能,降低系统的响应效率。在不同的表空间存储表数据和索引数据(如app_data和app_idx),我们可以避免这些比赛在生理的层面上,这两个表空间的数据文件放在不同的物理磁盘。
有一个单独的表空间,意味着可以独立地为独立的表数据和索引数据提供物理存储参数,但并不相互影响,毕竟表数据和索引数据具有不同的特性,这些特性直接影响物理存储参数。
此外,表数据和索引数据是独立存储的,同时也带来了数据管理和维护方面的问题,如果您正在迁移业务数据库,为了减少数据大小,只能将表数据的表空间移出,并通过重建索引在目标数据库中生成索引数据。
使用不同表空间的1.2个表数据和索引的SQL语法
指定的表数据和索引数据存储表空间语句的最简单形式如下所示。
在app_data存储表数据的表空间:
创建表t_order(order_id号码(10)不为空,表app_data…);
存储索引的表空间的数据app_idx:
创建t_order_item指数idx_order_item_order_id(order_id ASC)表空间app_idx;
如何在1.3 PowerDesigner操作
1)首先,你必须创建一个表空间,创建两个表空间列表中的表空间通过模型->表空间…
2)每个表的表空间指定存储在表中的数据。双击设计区域中的表,打开表属性设计窗口,切换到选项页面,并指定表数据的表空间,如图3所示。
3)为索引数据指定每个索引的存储表空间。在表属性中切换到索引页,其中列出所有表的索引,双击设置表空间的索引,在弹出索引属性窗口中切换到选项页,并指定索引表存储空间如下所示。
扩展表空间的问题:应用程序系统库的表空间可以更精细地划分。
首先,如果表中有字段,其中指定了一个特定的表空间,因为物理存储结构和一般数据管理策略中的数据类型非常不同,把它放在一个单独的表空间中,设置物理存储的参数是很方便的。
其次,需要考虑DML操作表数据的特点:根据DML(插入、更新、删除)操作频繁,几乎不会有一个单独的表空间的任何DML操作的数据,因为很少有DML操作台可与诸如PCTFREE的物理参数特征线的设置可以设置0。指定的buffer_pool保持,为了在保持数据缓冲等缓存数据,这是不是唯一的一个。
另外,不同的业务模块可以根据业务需求分别存储,这主要是作为备份问题,假设业务数据很强,业务数据不那么重要,我们可以分别存储它们,从而建立不同的备份策略。
当然,表空间的细化也会带来复杂的管理和部署。要根据企业的需要合理地平衡表空间,以达到最佳的管理和绩效。
{分页}
2、显式键列设置反向键索引
在2页{ 1 } { 2 } { 3 }下一页中看到的Oracle教程是优化Oracle库表设计的一系列方法。1反向索引索引的原理和用法。
我们知道,Oracle自动设置为表的主键列的索引,这是一个普通的默认索引B树索引B树索引,默认情况下,不是主键值被添加为理想(增加或减少),这是因为如果索引列的值有一个严格的秩序,随着数据行的插入索引树的水平迅速增加。搜索指数是多少我的I/O读写和索引树的水平成正比。也就是说,一个5级的B树索引最多可以参加5次我 / O操作时,索引数据最后读。因此,降低指数的高低来调整索引性能的重要途径。
如果索引列的数据被插入在严格有序,B树索引树将成为斜不对称的树
如果索引列的数据以随机值的方式插入,我们将得到一个对称的索引树,如图6所示。
比较图5和图6,搜索图5中的块需要5个I/O操作,而图6只需要3个I/O操作。
由于索引列的数据从所获得的序列,顺序不能避免,但在索引中,Oracle允许索引列值的反向,即预列值反位,如10001000110011101111100后值反后将是0001100111010011。很明显,有序数据点的反向处理更随机,和索引树更对称,从而提高表的查询性能。
但是反向索引索引也有它的局限性:如果在WHERE语句中,索引列值范围的需要,例如,在中间,那么此时不能使用反向索引索引,Oracle将执行一个完整的表扫描;只使用反向索引索引列和比较操作,反向键索引将被使用。
2.2 SQL反向索引索引语句
我们回到上面的例子,从序列的t_order和主键值t_order_item,主键值是严格的顺序,所以我们应该摆脱默认Oracle为指标,明确指定一个反向键索引方式是关键。
order_id的t_order表的主键,主键是pk_order和。我们在order_id柱建立反向索引idx_order_id,让pk_order_id使用此索引。它的SQL语句如下所示:
确保SQL语句创建idx_order_id是以前的pk_order主键的SQL语句,因为主键需要参阅反向键索引。
因为主键列的数据是唯一的,独特的idx_order_id增加使这一独特类型的指标。
2.3如何操作PowerdDesigner
1)首先,你需要建立一个为order_id柱反向键索引。打开t_order的表的属性窗口,切换到索引页,并创建一个索引命名idx_order_id.after填写指标名称,双击指标,弹出索引属性窗口中,选择在窗口列的order_id列。然后,切换到选项页,设置如图7反向键索引。
2)显式指定使用该指标的主要关键pk_order。开关在表格属性窗口的关键页面,默认情况下,由关键名称指定的t_order PowerDesigner KEY1,我们更名为pk_order,双击键属性键,弹出窗口,切换到选项页上,根据图8 pk_order idx_order_id。
不可否认,PowerDesigner确实是一个数据库设计工具是目前业界最强大和易于使用的,但不幸的是,当我们指定一个表的主键索引,表创建一个主表为问题:创建索引表:
我们可以调整SQL语句创建PowerDesigner的设置,并创建表和索引的SQL语句,然后创建SQL语句添加主键和外键的表实现了曲线救国的目的。请看下一步。
3)转移数据库配置窗口通过菜单数据库->生成数据库,切换到keysindexes页面,设置如图9:
在这里,我们取消主键和外键的选项,并对索引进行检查,以实现只生成表的索引SQL语句的目的。
单击ok后
除了此设置,还必须切换到表视图页并取消所有选项,以避免重新生成创建表的语句。
{分页}
三.对列表外关键指标改为压缩式
3.1压缩指数的原理及应用
在前面的例子中,因为一个订单对应多个订单项,对t_order_item的order_id场总是有重复的值,如:
创建一个普通的未压缩的B树索引的order_id列和索引数据的物理存储如下:
重复值的索引块order_id出现反复,这不仅增加了存储空间的需求,还需要读更多的索引数据块在查询时,查询的性能也会降低。让我们看看压缩索引数据存储一看。
压缩型指标消除了重复的索引值,与ROWID列值的索引存储在一起。这样,不仅节省了存储空间,又提高了查询的效率,这是最好的两个世界。
在查询的主从表如t_order和t_order_item案例中,我们通常需要使用外键查询所有相关记录的子表,所以它是建立压缩指标,在子表的外键很合适。
压缩类型索引的3.2 sql语句
SQL语句创建一个压缩的指标是非常简单的,并创建一个压缩指数的t_order_item的order_id SQL如下:
将压缩关键字附加到创建索引的语句中是必要的。
3.3 PowerDesigner如何创建一个压缩指数
1)公开对t_order_item表表属性窗口,切换到索引页,并创建一个索引命名为order_id idx_order_item_order_id柱。
2)双击idx_order_item_order_id弹出指标属性窗口,切换到选项页,并按图13设置指标为压缩型。
4、构建符合需求的复合索引索引
设计师要满足以下两组合查询通过idx_order_composite综合指数在t_order表:
客户端+ order_date + is_shipped
order_date + is_shipped
为了便于阐述,我们特别列出的idx_order_composite SQL语句的再创作:
事实上,在order_date +客户端+ is_shipped三列在查询的执行将应用于该指标的复合条件,与该指标在order_date +使用is_shipped复合查询不是在实现上市,从而会导致全表扫描操作。
You can use many tools to understand the execution plan of the query statement, and query the execution plan of the two complex queries by SET AUTOTRACE ON:
打开sql加号并输入以下语句:
分析的实施计划如下:
可以看出,Oracle首先使用idx_order_composite得到记录的rowid,满足条件,然后返回记录的ROWID。
和下面的查询语句:
实施计划如下:
很显然,Oracle可以在t_order表扫描全表和不使用idx_order_composite指数。
对于复合列索引,我们得出的结论是:
Oracle教程,是在下一页上看到{ 1 } { 2 } { 3 }下一页是一些优化Oracle库表的设计方法。假设它是在col_1,col_2,…col_n建立在这些列综合指数:
只有在声明中col_1查询(的复合指数的第一场)将使用该复合索引,而不col_1查询将不使用此复合索引。
回到我们的例子,你是如何建立符合两个查询,满足客户+ order_date + is_shipped和order_date + is_shipped索引
考虑到is_shipped列基数很小,只可能有两个值:1.in:这种情况下,有两种方法:第一,建立order_date +客户端+ is_shipped和order_date + is_shipped复合指标;其次,建立客户和order_date柱分别指数,而is_shipeed列不指数。
第一种方案最快的查询效率,但由于客户和order_date重复索引中的两倍,它占用的存储空间较大。第二方案,客户端和order_date,将不会出现在索引存储两次。它节省了更多的空间,查询效率略低于第一个查询,但影响不大。
我们用二方案来创建索引idx_client和idx_order_date分别为客户端和order_date,和执行的计划是:客户端+ order_date + is_shipped。
执行计划时,组合条件是order_date + is_shipped是:
通过这种转换,我们得到了一个满足两个查询组合的执行计划。
总结
本文所述主从表的顺序结构非常简单,但其粗略的设计包含了许多问题,这也是许多数据库设计者不容易理解Oracle物理存储结构的原因。
一般来说,这种设计并不会导致系统严重的性能问题,但最好的是每一个优秀的软件设计师的素质,此外,设计者必须意识到这样一个规律:要提高性能和质量,在编码层往往需要比设计水平更困难的薪酬。
在oracle中提高数据库性能需要考虑许多问题,本文介绍了一些最常见的问题,总结了提高数据库操作性能的方法和一些误区。
对于大表,我们可以考虑创建分区表。分区表包括范围分区、哈希分区、列表分区和哈希分区。
考虑适当数量的数据冗余。例如,如果业务表单有审批状态,审批必须采取许多步骤。每一步对应于批准表的记录。最后的批准记录决定了业务的状态。我们可以在业务表中存储一个批准状态的标志,以取消需要通过关联审批表单获得业务批准状态的复杂表查询。
不要做太多的关联表的查询,一些几乎没有变化的数据表,如性别、学历、婚姻状况和其他表可以在应用程序启动时考虑下载应用程序的内存缓存,获取从数据库结果集,然后用表这些数据缓存将这些表的代码字段的程序,而不是通过在数据库表之间的关联查询这些领域。
我经常看到一些令人瞠目的设计:频繁的DML(插入、更新、删除)的基表场运行一些低(如性别、婚姻状况)在一个位图索引,位图索引是一件好事,但它有着广泛的应用。在OLTP系统,位图索引不应该出现在需要频繁的DML操作表。位图索引只适合DSS系统,很少进行DML操作。此外,聚类和索引组织表也更适合DSS系统比OLTP系统。上一页
{ { 1 } { 2 } { 3 }的最后一页