创建B树索引之前,为了慎重起起见,有必要从架构层面考虑一些将影响可维护性和可用性的问题。以下是建立索引之前,应该考虑的架构性问题。
.在创建索引之前,首先对它的大小进行估计。
.考虑指定表索引的表空间(与表分离)。这使得分开管理表和索引变得更轻松,如备份和恢复任务。
.允许对象从它闪的表空间继承存储参数。
.定义创建索引时要使用的命令标准。
1 在创建索引前估计索引的大小
一张大表上创建索引之前,可能需要估计它将会占用的空间大小。预测索引大小最好的方法是在测试环境中创建它,测试环境中有生产环境的典型数据集。如果不能建立生产数据的完整副本,那么经常可以用数据的一个子集来推断在生产中所需索引空间的大小。如果你没有使用削减的生产数据的奢侈条件,还可以使用dbms_space.create_index_cost存储过程来估算索引的大小。例如,如下代码估算了在cust表的first_name列上创建索引的大小:
SQL> set serverout on SQL> exec dbms_stats.gather_table_stats(user,'CUST'); PL/SQL procedure successfully completed. SQL> variable used_bytes number SQL> variable alloc_bytes number SQL> exec dbms_space.create_index_cost('create index cust_idx2 on cust(first_name)',:used_bytes,:alloc_bytes); PL/SQL procedure successfully completed.
下面是这个例子的一些示例输出:
SQL> print :used_bytes USED_BYTES ---------- 7490 SQL> print :alloc_bytes ALLOC_BYTES ----------- 65536
used_bytes变量给出了索引数据需要多少空间的估计。alloc_bytes变量提供了将在表空间内分配多大空间的估计。
下一步,创建索引。
SQL> create index cust_idx2 on cust(first_name); Index created.
用如下查询显示所占用的空间的实际数额:
SQL> select bytes from user_segments where segment_name='CUST_IDX2'; BYTES ---------- 65536
输出显示空间分配字节数的估计量等于实际使用量。
根据记录数,列数,数据类型和统计数据的准确性,输出的结果可能会有所不同。除初始大小之外,还要牢记随着记录插入到表中,该索引将增大。必须对索引占用的空间进行监控,并确保有足够的磁盘空间,以适应未来的增长需求。
2 为索引创建单独的表空间
对于关键的应用程序,必须提前考虑表和索引会消耗多少空间,以及它们增长的速度有多快。空间消耗和对象的增长对数据库可用性有直接影响。如果空间用尽了,那么数据库将变得不可用。最好的管理办法是,针对空间要求创建表空间,并在创建对象时明确指定表空间名。考虑到这一点,我们建议将表和索引分别保存到单独的表空间。考虑以下原因。
.支持采用不同的备份和恢复要求。你可能希望灵活地用与备份表不同的频率来备份索引。或者可以选择不备份索引,因为你知道可以重新创建它们。
.如果让表或索引从表空间继承它的存储特性,使用单独的表空间可以为表空间内创建的对象量身定制存储属性。表和索引往往有不同的存储要求(如区的大小,记录等)。
.运行维护报告时,如果报告针对不同的表空间具有不同的节(section),有时管理表和索引会更容易。
如果这些原因出现在你的环境中,那么可能值得付出额外的努力,对表和索引采用不同的表空间。如果你没有前面提到的任何需要,那么把表和索引保存在相同的表空间是不错的选择。
DBA经常出于性能的原因,考虑把索引放置在单独的表空间。如果你有从头开始建立存储系统的奢侈条件,可以把挂载点(mount point)设置为有自己的磁盘和控制器,那么可能会看到把表和索引存储在不同表空间的一些IO上的好处。如今,存储管理员往往会分配给你的SAN中的一大片存储,并且无法保证数据和索引将存储在单独的磁盘和控制器上。因此,把表和索引存储在不同表空间的做法,通常对提高性能没什么帮助。换句话说,性能获得提高不是通过将表和索引存储到不同的表空间实现的,而是由于在所有可用的设备上均匀地分布IO实现的。
下面的代码显示的是为表和索引单独建立表空间的例子。它使用固定大小的区和自动段空间管理(ASSM)创建了本地管理的表空间。
SQL> create tablespace reporting_data datafile '+DATA/JYCS/reporting_data01.dbf' size 1G extent management local uniform size 1M 2 segment space management auto; Tablespace created. SQL> create tablespace reporting_index datafile '+DATA/JYCS/reporting_index01.dbf' size 500M extent management local uniform size 128K 2 segment space management auto nologging; Tablespace created.
我们更倾向于使用统一大小的区,因为这确保了表空间内存的所有区大小相同,从而减少了对象创建和删除时的碎片。ASSM的功能允许Oracle自动管理存储属性,而以前这需要手动监测和由DBA维护。
3 从表空间继承存储参数
创建表或索引时,有几个与表空间相关的技术细节需要注意。例如,如果创建表和索引时不指定存储参数,则表和索引会继承表空间的存储参数。这是在大多数情况下所需的行为。这样就可以不必手动指定这些参数。如果需要创建一个具有与表空间不同的存储参数的对象,那么用create table/index语句来实现。
此外,请记住,如果不明确指定表侬间,默认情况下,表和索引创建在用户的默认表空间中。在开发和测试环境中,这是可以接受的。对于生产环境,则应该考虑在create table/index语句中明确命令表空间。
4 命令标准
在创建和管理索引时,制定一些命名标准是非常可取的。考虑以下因素.
.当错误消息中包含表示表,索引类型等的信息时,简化了对问题的诊断。
.显示索引信息的报告更容易被分组,因此更具可读性并更容易地发现其中的规律和问题。鉴于这些需求,这里有一些示例索引命名指南。
.主键索引名称应该包含表名和一个后缀,如_UKN,其中N是一个数字。
.外键列上的索引应包含外键表和一个后缀,如_FKN,其中N是一个数字。
.对于不用于约束的索引,使用表名和一个后缀,如_IDXN,其中N是一个数字。
.基于函数的索引的名称应包含表名和一个后缀,如_FCN,其中N是一个数字。
一些厂商在命名索引时使用前缀。例如,主键索引将被命名为PK_CUST(而不是CUST_PK)。所有这些不同的命名标准都是有效的。