优化Oracle库表设计的若干方法(4)
来源:asp之家 发布时间:2010-07-16 13:24:00
3、将子表的外键列的索引改为压缩型
3.1 压缩型索引的原理和用途
在前面的例子中,由于一条订单会对应多条订单条目,所以T_ORDER_ITEM的ORDER_ID字段总会出现重复的值,如:
在ORDER_ID列上创建一个普通未压缩的B-Tree索引,则索引数据的物理上的存储形式如下:
ORDER_ID的重复值在索引块中重复出现,这样不但增加了存储空间的需求,而且因为查询时需要读取更多的索引数据块,所以查询性能也会降低=。让我们来看一下经过压缩后索引数据的存储方式:
压缩型的索引消除了重复的索引值,将相同索引列值所关联的ROWID存储在一起。这样,不但节省了存储空间,查询效率也提高了,真可谓两全齐美了。
对象T_ORDER和T_ORDER_ITEM这样的主从表进行查询时,一般情况下,我们都必须通过外键查询出子表所有关联的记录,所以在子表的外键上建立压缩型的索引是非常适合的。
3.2 压缩型索引的SQL语句
创建压缩型索引的SQL语句非常简单,在T_ORDER_ITEM的ORDER_ID上创建压缩型索引的SQL如下所示:
需要在创建索引的语句后附上compress关键字就可以了。
3.3 PowerDesigner如何创建压缩型索引
1) 打开T_ORDER_ITEM表的Table Properties的窗口,切换到Indexes页,为ORDER_ID列创建一个名为IDX_ORDER_ITEM_ORDER_ID的索引。
2) 双击IDX_ORDER_ITEM_ORDER_ID弹出Index Properties窗口,切换到Options页,按图 13将索引设置为压缩型:
4、建立满足需求的复合键索引
设计人员希望通过T_ORDER表上的IDX_ORDER_COMPOSITE复合索引满足以下两种组合条件的查询:
·CLIENT + ORDER_DATE + IS_SHIPPED
·ORDER_DATE + IS_SHIPPED
为方便阐述,我们特地将IDX_ORDER_COMPOSITE的创建SQL语句再次列出:
事实上,在CLIENT + ORDER_DATE + IS_SHIPPED 三列上所执行的复合条件查询会应用到这个索引,而在ORDER_DATE + IS_SHIPPED列上所执行的复合查询不会使用这个索引,因而将导致一个全表扫描的操作。
可以用许多工具来了解查询语句的执行计划,通过SET AUTOTRACE ON来查询以上两个复合查询的执行计划:
打开SQL/Plus,输入以下的语句:
分析得到的执行计划为:
可见Oracle先利用IDX_ORDER_COMPOSITE得到满足条件的记录ROWID,再通过ROWID返回记录。
而下面查询语句:
的执行计划则为:
很明显,Oracle在T_ORDER表上执行了一个全表扫描的操作,没有用到IDX_ORDER_COMPOSITE索引。
对复合列索引,我们得出这个结论:
假设在COL_1,COL_2,…,COL_n这些列上建立了一个复合索引:
则只有WHERE语句上包含COL_1(复合索引的第一个字段)的查询才会使用这个复合索引,而未包含COL_1的查询则不会使用这个复合索引。
回到我们的例子,如何建立满足CLIENT + ORDER_DATE + IS_SHIPPED和ORDER_DATE + IS_SHIPPED两种查询的索引呢?
考虑到IS_SHIPPED列基数很小,只有两个可能的值:0,1。在这种情况下,有两种方案:第一,分别为CLIENT + ORDER_DATE + IS_SHIPPED和ORDER_DATE + IS_SHIPPED建立一个复合索引;第二,分别在CLIENT和ORDER_DATE列上建立一个索引,而IS_SHIPEED列不建立索引。
第一种方案的查询效率最快,但因为CLIENT和ORDER_DATE在索引中会重复出现两次,占用较大的存储空间。第二种方案CLIENT和ORDER_DATE不会在索引存储出现两次,较为节省空间,查询效率比之于第一种方案会稍低一些,但影响不大。
我们采用第二种方案为CLIENT和ORDER_DATE分别创建索引IDX_CLIENT和IDX_ORDER_DATE,组合查询条件为CLIENT + ORDER_DATE + IS_SHIPPED时的执行计划为:
而组合条件为ORDER_DATE + IS_SHIPPED时的执行计划为:
通过这样的改造,我们得到了一个满足两种组合查询的执行计划。


猜你喜欢
- 语法 SET IDENTITY_INSERT [ database.[ owner.] ] { table } { ON | OFF } 参
- 为什么要用缓存?首先说,为什么要用缓存的,由于Django是 * 站,所有每次请求均会去数据进行相应的操作,当程序访问量大时,耗时必然会更加
- 在批评Python的讨论中,常常说起Python多线程是多么的难用。还有人对 global interpreter lock(也被亲切的称为
- 爬取网站为:http://xiaohua.zol.com.cn/youmo/查看网页机构,爬取笑话内容时存在如下问题:1、每页需要进入“查看
- import cv2 as cvimport numpy as npimport matplotlib.pyplot as plt# 设置兼
- 说明一直想做一个基于VUE的项目,但是因为项目往往要涉及到后端的知识(不会后端真的苦),所以就没有一直真正的动手去做一个项目。直到发现Git
- Python的装饰器的英文名叫Decorator,当你看到这个英文名的时候,你可能会把其跟Design Pattern里的Decorator
- 今天花了一些时间搭了一个博客系统,虽然并没有相关于界面的美化,但是发布是没问题的。开发环境操作系统:windows 7 64位 Django
- 现在jquery应用的越来越多, 有些同学在享受爽快淋漓coding时就将性能问题忽略了, 比如我. jquery虽
- 项目需要就在现有的服务器上面重新安装了个mysql服务器,还挺费劲儿呢,因为之前都是在我的笔记本上面试验的,它的系统是Ubuntu的,什么路
- 本文实例讲述了python通过imaplib模块读取gmail里邮件的方法。分享给大家供大家参考。具体实现方法如下:import imapl
- 我们都知道如果想让电脑运行更多的程序,就要增加它的配置才能带动。在之前的学习中,我们已经对函数的打印print有所了解,但是遇到更加复杂的对
- 本文实例讲述了Thinkphp5.0框架视图view的循环标签用法。分享给大家供大家参考,具体如下:volist标签:<!-- 使用v
- 首先,需要获取任意知乎的问题,只需要你输入问题的ID,就可以获取相关的页面信息,比如最重要的合计有多少人回答问题。问题ID为如下标红数字编写
- Python 作为当前最热门的编程语言之一,不仅仅是因为它的学习成本低、入门容易,还因为它具有丰富的生态环境,包括内置的模块以及第三方的库,
- 上一篇:微软建议的ASP性能优化28条守则(7)技巧 22:尽可能使用 Server.Transfer 代替 Response.Redire
- 一、说明 numpy.ufunc是什么函数?答
- 本文实例讲述了Python切片操作。分享给大家供大家参考,具体如下:在很多编程语言中,针对字符串提供了截取函数,其实目的就是对字符串切片。P
- split()介绍函数:split()Python中有split()和os.path.split()两个函数,具体作用如下:split():
- MySQL是“世界上最为流行的开放性数据库”,至少对于MySQL Web站点会这样。但无论