打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Db2有关索引的学习笔记 - DB2 - JAVA诺曼底 java|诺曼底|web开发|s...

1.介绍

1.1 概述

建表时,为提高检索速度和保证列无重复行,对表的任何一列或多列都可建索引,而该列称为索引(key column)。建索引有3种目的:

1.为建索引列提供快速检索。改善某些特殊列或值的查询性能。

2.为建索引提供升序或降序功能。该功能对有ORDER BY和GROUP BY子句的查询特别有用。加快这些子句的实施。当然,这些子句也可以不用索引实施,系统只作简单的分类处理。

3.为表中某些列保证不出现重复行。因为在建唯一索引时,如列中有重复行,建唯一索引失败返回,利用这一性质,可处理列中重复行。

在表中,用户可按自己需求,组合各列作为索引项列,并对它建索引,但是,建索引要花费一定开销。主要指空间占用的开销。因为,建索引时,对列值要全部复制,再加上指针,都需占用空间。另一方面开销是在发生表修改时,每次对表的列值修改,相应索引必然要改。实际上,数据库的维护工作中,索引维护经验是很重要的实践内容。虽然,关系型数据库的数据,独立于库模型,允许增加或删除索引。但是,查询的每次执行,与索引的选择是相关的。

在UDB中,只有三种方法去实施对特殊列保证无重复行。一种方法是对列建唯一索引,另一种方法是对该列指定主关键字,最后一种方法是对该列建唯一关键字。如指定SERIALNO为EMPLOYEE表的主关键字或唯一关键字,为保证列无重复的行,对它建唯一索引。对一个表来说,主关键字只有一个,而唯一关键字可以有多个。

1.2 分类

索引的分类

按照索引的应用和结构可以有不同的分类方法。

1) 聚集索引和非聚集索引

聚集索引不仅是把关键字相近的记录用指针逻辑地连在一起,而且把关键字相近的记录物理地存放在一起。每个表中仅能有一个聚集索引。我们一般建的索引均是非聚集索引,如要建立聚集索引,就要在建索引的命令中加CLUSTER子句。

2) 唯一关键字索引和非唯一关键字索引

唯一关键字索引主要是建索引的关键字的值必须唯一,特别是在已存在的表上建唯一索引时,如有关键字的值不唯一,那么建索引失败。对主关键字和唯一关键字,系统会自动建唯一索引。在建索引时,要加UNION的子句。

3) 复合关键字索引和包含关键字索引

如建索引,系统会针对关键字的升序或降序方式来帮助提高查询性能,对复合关键字会逐个地按升序或降序来索引。而对包含关键字索引,只对所要索引的关键字按序进行,对所包含的字段不按序进行,只是在索引中增加了字段,常常是对唯一关键字索引做包含字段。

1.3 索引的设计

1.3.1 准则

1. 一个表如果建有大量索引会影响 INSERTUPDATE DELETE 语句的性能,因为在表中的数据更改时,所有索引都须进行适当的调整。另一方面,对于不需要修改数据的查询(SELECT 语句),大量索引有助于提高性能,因为数据库有更多的索引可供选择,以便确定以最快速度访问数据的最佳方法。

2. 组合索引:组合索引即多列索引,指一个索引含有多个列。一个组合索引相当于多个单列索引,如索引(ColA, ColB, ColC)至少相当于(ColA)(ColA, ColB)(ColA, ColB, ColC)三个索引。

2. 覆盖的查询可以提高性能。覆盖的查询是指查询中所有指定的列都包含在同一个索引(组合索引)中。例如,如果在一个表的 ab c 列上创建了组合索引,则从该表中检索 a b 列的查询被视为覆盖的查询。创建覆盖一个查询的索引可以提高性能,因为该查询的所有数据都包含在索引自身当中;检索数据时只需引用表的索引页,不必引用数据页,因而减少了 I/O 总量。尽管给索引添加列以覆盖查询可以提高性能,但在索引中额外维护更多的列会产生更新和存储成本。

3. 对小型表进行索引可能不会产生优化效果,因为数据库在遍历索引以搜索数据时,花费的时间可能会比简单的表扫描还长。

4. 应使用 SQL 事件探查器和索引优化向导帮助分析查询,确定要创建的索引。为数据库及其工作负荷选择正确的索引是非常复杂的,需要在查询速度和更新成本之间取得平衡。窄索引(搜索关键字中只有很少的列的索引)需要的磁盘空间和维护开销都更少。而另一方面,宽索引可以覆盖更多的查询。确定正确的索引集没有简便的规则。经验丰富的数据库管理员常常能够设计出很好的索引集,但是,即使对于不特别复杂的数据库和工作负荷来说,这项任务也十分复杂、费时和易于出错。可以使用索引优化向导使这项任务自动化。有关更多信息,请参见索引优化向导。

5. 可以在视图上指定索引。

6. 可以在计算列上指定索引。

7. 避免在索引列上使用IS NULLIS NOT NULL。避免在索引中使用任何可以为空的列,数据库将无法使用该索引。对于单列索引,如果列包含空值,索引中将不存在此记录;对于复合索引,如果每个列都为空,索引中同样不存在此记录. 如果至少有一个列不为空,则记录存在于索引中。

8. 如果经常检索包含大量数据的表中的少于15%的行则需要创建索引。

9. 衡量索引效率的 95/5 规则:如果查询的结果返回的行数少于表中所有行的5%,则索引是检索数据的最快方法,如果查询的结果超过5%,那么通常使用索引就不是最快的方式。

10.主关键字和唯一关键字所在的列自动具有索引,但外部关键字没有自动索引。

1.3.2 规范

1.索引中的最大列数是 64。若是对类型表建立索引,则最大列数是 63。索引键的最大长度不能大于页大小的索引键长度限制。

2.
若要建立索引的表是空的,则仍会创建索引,但是在装入该表或插入行之前,不会建立任何索引条目。若该表不是空的,则数据库管理器在处理 CREATE INDEX 语句时会建立索引条目。

3.
对于集群索引,将新行实际插入具有相似键值的现有行附近。这可改善查询性能,因为它导致数据页的访问模式更线性化,且产生更有效的预取。

若要让主键索引成为集群索引,不应在 CREATE TABLE 中指定主键。一旦创建了主键,就不能修改相关的索引。而是执行不带主键子句的 CREATE TABLE。然后,发出 CREATE INDEX 语句,并指定集群属性。最后,使用 ALTER TABLE 语句添加与刚创建的索引对应的主键。将把此索引用作主键索引。

通常,若集群索引是唯一的,则集群维护起来就更有效率。

2.如何建立索引

 建立索引有两种方法:

一种是采用命令行方式,另一种是采用图形用户界面(GUI

(1)命令行方式

语句:

CREATE <UNIQUE> INDEX <index name> ON <table name>

(

column 1 <ASC | DESC> ,

column 2 <ASC | DESC> ...

)

UNIQUE 属性告诉 DB2,索引必须强制所有插入值的唯一性。

如果结果集是以升序和降序两种方式排序的,ALLOW REVERSE SCANS 会告诉 DB2 在索引中包括附加的指针,以允许在记录中有效地进行正向和反向链接。

所创建的索引可以在控制中心中查看到。

DB2能够向正在创建的索引中添加另外的列。CREATE INDEX 命令允许用户指定那些不属于实际索引但因为性能原因而保存在索引记录中的列。

CREATE UNIQUE INDEX ON EMPLOYEE (EMPNO) INCLUDE (LASTNAME,FIRSTNAME)

对于索引中包含的列而言,索引必须是 UNIQUE 的。当创建索引时,另外的列被添加到索引值中。索引不使用这些值进行排序或确定唯一性,但可以在满足 SQL 查询时使用它们。例如,下列 SELECT 语句将不需要读取实际数据行:

SELECT LASTNAME, FIRSTNAME FROM EMPLOYEE WHERE EMPNO < '000300'>

要在表上创建群集索引,将 CLUSTER 关键字附加到 CREATE INDEX 命令的末尾,例如: CREATE INDEX DEPTS-IX ON EMPLOYEE(WORKDEPT) CLUSTER

(2)GUI方式

进入控制中心,在左边的树中展开要创建索引所在的的数据库,并点击右键,选择索引向导。

3.如何发挥索引的功能

3.1索引的快速排序查询

举例:

在命令行中为表studentid int not null,name varchar(20))新建索引:

命令如下:

Sql 语句:

CREATE  UNIQUE INDEX  INDEXTABLE ON  STUDENT (ID,NAME)  PCTFREE 10 MINPCTUSED 10 ALLOW REVERSE SCANS  PAGE SPLIT SYMMETRIC COLLECT  SAMPLED DETAILED  STATISTICS

界面如下所示:

说明:要避免某些排序,只要有可能,就通过使用 CREATE UNIQUE INDEX 语句定义主键和唯一键。

要改善数据检索,将 INCLUDE 列添加至唯一索引。合适的列为:

被频繁访问,因此可从纯索引访问中受益的列。

不需要用来限制索引扫描的范围的列

不影响索引键的排序或唯一性的列。

要有效访问小表,使用关系索引来优化对含有较多数据页的表的频繁查询,数据页数记录在 SYSCAT.TABLES 目录视图的 NPAGES 列中。您应该:

根据连接表时要使用的任何一列来创建索引。

根据将用于定期搜索特定值的任何列来创建索引。

要有效地搜索,决定对键使用升序还是降序,这取决于将最常使用的顺序。尽管当在 CREATE INDEX 语句中指定了 ALLOW REVERSE SCANS 参数时可以按逆向方向搜索值,但是,执行按指定索引顺序的扫描比执行逆向扫描稍微更快一些。

要保存索引维护成本和空间:

避免创建的关系索引是这些列上其他索引键的部分键。例如,如果列 ab c 上有索引,则列 a b 上的第二个索引一般用处不大。

不要在所有列上任意创建关系索引。不必要的索引不仅使用空间,而且导致大量准备时间。当使用具有动态编程连接枚举的优化级别时,这对于复杂的查询特别重要。

使用下列一般规则来确定将为表定义的关系索引的典型数目。此数目根据数据库的主要使用来确定:

对于联机事务处理(OLTP)环境,创建一个或两个索引

对于只读查询环境,可以创建 5 个以上索引

对于混合查询和 OLTP 环境,可以创建 2 5 个索引。

要提高对父表执行删除和更新操作的性能,在外键上创建关系索引。

要提高涉及到 IMMEDIATE INCREMENTAL MQT DELETE UPDATE 操作的性能,对 MQT 的隐含唯一键创建唯一关系索引,该隐含唯一键是 MQT 定义的 GROUP BY 子句中的列。

对于快速排序操作,在频繁用于排序关系数据的列上创建关系索引。

要提高多列关系索引的连接性能,如果第一个键列有多项选择,则使用最常用“=”(等值连接)谓词指定的那一列,或使用如第一个键那样具有最多单值的那些列。

要帮助新插入的行根据索引进行集群并避免页分割,定义一个集群索引。集群索引应显著减少重组表的需要。

当定义表时使用 PCTFREE 关键字来指定页上应该留下多少可用空间,才能允许将插入行适当地放在页上。也可以指定 LOAD 命令的 pagefreespace MODIFIED BY 子句。

要启用联机索引整理碎片,创建关系索引时使用 MINPCTUSED 选项。MINPCTUSED 指定索引叶子页中最小使用空间量的阈值并启用联机索引整理碎片。如果这些删除实际上从索引页除去键,则这可以在键删除期间以性能损失为代价而减少重组的需要。

在新建索引之前向数据表中添加数据,添加数据之前表中的记录为

所添加的数据为:

insert into student values(8,'Hh')

insert into student values(6,'a')

insert into student values(7,'a')

insert into student values(16,'a')

insert into student values(54,'a')

insert into student values(65,'a')

insert into student values(14,'a')

insert into student values(25,'a')

insert into student values(56,'a')

insert into student values(64,'a')

insert into student values(27,'a')

insert into student values(68,'a')

insert into student values(45,'a')

insert into student values(87,'a')

insert into student values(47,'a')

insert into student values(23,'a')

insert into student values(89,'a')

可以看到student表中的id不是按照一定顺序输入的。因此在新建索引之前,插入的记录为如下所示:

当创建索引后,显示的记录为

检测新建的索引,确定此索引是否是对所有以后添加的记录同时保持这个规则:

在命令行中输入命令:insert into student values(9,'a')

然后再输入命令查询表studentselect * from student

界面显示如下所示:

可以看到所添加的记录仍然保持升序规则。

CREATE INDEX  INDEXmytest ON  mytest (name desc)  PCTFREE 10 MINPCTUSED 10 ALLOW REVERSE SCANS  PAGE SPLIT SYMMETRIC COLLECT  SAMPLED DETAILED  STATISTICS

在建立索引之前,从表steamwatermonitor中我们可以查看samplingtime的值,如下面所示:

对时间进行降序排列,并对每次查询生效。

建立索引的命令如下所示:

CREATE INDEX  INDEXSAMPLINGTIME  ON  SteamWaterMonitor (samplingTime desc)  PCTFREE 10 MINPCTUSED 10 ALLOW REVERSE SCANS  PAGE SPLIT SYMMETRIC COLLECT  SAMPLED DETAILED  STATISTICS

测试索引的有效性:

插入记录

insert into STEAMWATERMONITOR(ACCRUVOLUME,PRESSURE,SAMPLINGTIME,STATIONID,TEMP,VOLUME) values(100,10,'2007-02-24 10:35:00',1,100,100)

再查询samplingtime

在建立索引indexstationid之前,从表steamwatermonitor中我们可以查看stationid的值,如下面所示:

建立索引indexstationid

语句为:

CREATE INDEX  INDEXSTATIONID  ON  SteamWaterMonitor (stationid)  PCTFREE 10 MINPCTUSED 10 ALLOW REVERSE SCANS  PAGE SPLIT SYMMETRIC COLLECT  SAMPLED DETAILED  STATISTICS

查看

Sql语句测试

select * from steamwatermonitor where stationid>7 and stationid<60

显示结果如下所示:

select * from steamwatermonitor where date(samplingtime)>date('2007-02-12')

查询结果为

select * from steamwatermonitor where date(samplingtime) between date('2007-02-14') and date('2007-02-24')

显示结果为:

select * from steamwatermonitor where date(samplingtime)=date('2007-02-12')

select * from steamwatermonitor where date(samplingtime)=date('2007-02-12') and stationid=7

显示结果为:

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
MySql避免重复插入记录
SQL小知识 | 为什么 GROUP BY 之后不能直接引用原表中的列?
sql server 增删改(查太多了)
SQL语句之基础增删改查
SQL Server中的Merge关键字
10分钟学会 SQL 语言核心知识点!
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服