欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  数据库

mysql 目录建立规则

程序员文章站 2022-04-10 15:10:17
...

mysql 索引建立规则 索引创建规则:?1、表的主键、外键必须有索引;?2、数据量超过300的表应该有索引; 3、经常与其他表进行连接的表,在连接字段上应该建立索引 4、经常出现在Where子句中的字段,特别是大表的字段,应该建立索引;?5、索引应该建在选择性高

mysql 索引建立规则
索引创建规则:
?1、表的主键、外键必须有索引;
?2、数据量超过300的表应该有索引; 
 3、经常与其他表进行连接的表,在连接字段上应该建立索引
 4、经常出现在Where子句中的字段,特别是大表的字段,应该建立索引;
?5、索引应该建在选择性高的字段上; 
 6、索引应该建在小字段上,对于大的文本字段甚至超长字段,不要建索引;
?7、复合索引的建立需要进行仔细分析;尽量考虑用单字段索引代替: 
 A、正确选择复合索引中的主列字段,一般是选择性较好的字段;
?B、复合索引的几个字段是否经常同时以AND方式出现在Where子句中?单字段查询是否极少甚至没有?如果是,
则可以建立复合索引;否则考虑单字段索引; 
 C、如果复合索引中包含的字段经常单独出现在Where子句中,则分解为多个单字段索引;
?D、如果复合索引所包含的字段超过3个,那么仔细考虑其必要性,考虑减少复合的字段;
?E、如果既有单字段索引,又有这几个字段上的复合索引,一般可以删除复合索引;
?8、频繁进行数据操作的表,不要建立太多的索引;
?9、删除无用的索引,避免对执行计划造成负面影响; 以上是一些普遍的建立索引时的判断依据。
一言以蔽之,索引的建立必须慎重,对每个索引的必要性都应该经过仔细分析,要有建立的依据。
因为太多的索引与不充分、不正确的索引对性能都毫无益处:在表上建立的每个索引都会增加存储开销,
索引对于插入、删除、更新操作也会增加处理上的开销。另外,过多的复合索引,在有单字段索引的情况下,
一般都是没有存在价值的;相反,还会降低数据增加删除时的性能,特别是对频繁更新的表来说,负面影响更大。 

oracle的索引陷阱
一个表中有几百万条数据,对某个字段加了索引,但是查询时性能并没有什么提高,这主要可能是oracle的索引限制造成的。?
oracle的索引有一些索引限制,在这些索引限制发生的情况下,即使已经加了索引,oracle还是会执行一次全表扫描,查询的性能不会比不加索引有所提高,反而可能由于数据库维护索引的系统开销造成性能更差。?
下面是一些常见的索引限制问题。
?
1、使用不等于操作符(, !=)
下面这种情况,即使在列dept_id有一个索引,查询语句仍然执行一次全表扫描?
select * from dept where staff_num 1000;?
但是开发中的确需要这样的查询,难道没有解决问题的办法了吗??
有!?
通过把用 or 语法替代不等号进行查询,就可以使用索引,以避免全表扫描:上面的语句改成下面这样的,就可以使用索引了。?
select * from dept shere staff_num 1000;?
?
2、使用 is null 或 is not null
使用 is null 或is nuo null也会限制索引的使用,因为数据库并没有定义null值。如果被索引的列中有很多null,就不会使用这个索引(除非索引是一个位图索引,关于位图索引,会在以后的blog文章里做详细解释)。在sql语句中使用null会造成很多麻烦。?
解决这个问题的办法就是:建表时把需要索引的列定义为非空(not null)
?
3、使用函数
如果没有使用基于函数的索引,那么where子句中对存在索引的列使用函数时,会使优化器忽略掉这些索引。下面的查询就不会使用索引:?
select * from staff where trunc(birthdate) = '01-MAY-82';?
但是把函数应用在条件上,索引是可以生效的,把上面的语句改成下面的语句,就可以通过索引进行查找。?
select * from staff where birthdate ?
4、比较不匹配的数据类型
比较不匹配的数据类型也是难于发现的性能问题之一。
下面的例子中,dept_id是一个varchar2型的字段,在这个字段上有索引,但是下面的语句会执行全表扫描。?
select * from dept where dept_id = 900198;?
这是因为oracle会自动把where子句转换成to_number(dept_id)=900198,就是3所说的情况,这样就限制了索引的使用。
把SQL语句改为如下形式就可以使用索引?
select * from dept where dept_id = '900198';

?

?

二,

?各种索引使用场合及建议

?

(1)B*Tree索引。

常规索引,多用于oltp系统,快速定位行,应建立于高cardinality列(即列的唯一值除以行数为一个很大的值,存在很少的相同值)。

?Create index indexname on tablename(columnname[columnname...])

(2)反向索引。

B*Tree的衍生产物,应用于特殊场合,在ops环境加序列增加的列上建立,不适合做区域扫描。

?Create index indexname on tablename(columnname[columnname...]) reverse

(3)降序索引。

B*Tree的衍生产物,应用于有降序排列的搜索语句中,索引中储存了降序排列的索引码,提供了快速的降序搜索。

?Create index indexname on tablename(columnname DESC[columnname...])

(4)位图索引。

位图方式管理的索引,适用于OLAP(在线分析)和DSS(决策处理)系统,应建立于低cardinality列,
适合集中读取,不适合插入和修改,提供比B*Tree索引更节省的空间。

?Create BITMAP index indexname on tablename(columnname[columnname...])

在实际应用中,如果某个字段的值需要频繁更新,那么就不适合在它上面创建位图索引。
在位图索引中,如果你更新或插入其中一条数值为N的记录,
那么相应表中数值为N的记录(可能成百上千条)全部被Oracle锁定,
这就意味着其它用户不能同时更新这些数值为N的记录,其它用户必须要等第一个用户提交后,
才能获得锁,更新或插入数据,bitmap index它主要用于决策支持系统或静态数据。

(5)函数索引。

B*Tree的衍生产物,应用于查询语句条件列上包含函数的情况,
索引中储存了经过函数计算的索引码值。可以在不修改应用程序的基础上能提高查询效率。

索引创建策略?
1.导入数据后再创建索引?
2.不需要为很小的表创建索引?
3.对于取值范围很小的字段(比如性别字段)应当建立位图索引?
4.限制表中的索引的数目?
5.为索引设置合适的PCTFREE值?
6.存储索引的表空间最好单独设定

唯一索引和不唯一索引都只是针对B树索引而言.?
Oracle最多允许包含32个字段的复合索引?
由此估计出一个查询如果使用某个索引会需要读入的数据块块数。
需要读入的数据块越多,则 cost 越大,Oracle 也就越有可能不选择使用 index

?

三,

能用唯一索引,一定用唯一索引?
能加非空,就加非空约束?
一定要统计表的信息,索引的信息,柱状图的信息。?
联合索引的顺序不同,影响索引的选择,尽量将值少的放在前面?
只有做到以上四点,数据库才会正确的选择执行计划。

====================================================================================================================================

 一、 ROWID的概念

  存储了row在数据文件中的具体位置:64位编码的数据,A-Z, a-z, 0-9, +, 和 /,

  row在数据块中的存储方式

  SELECT ROWID, last_name FROM hr.employees WHERE department_id = 20;

  比如:OOOOOOFFFBBBBBBRRR

  OOOOOO:data object number, 对应dba_objects.data_object_id

  FFF:file#, 对应v$datafile.file#

  BBBBBB:block#

  RRR:row#

  Dbms_rowid包

  SELECT dbms_rowid.rowid_block_number('AAAGFqAABAAAIWEAAA') from dual;

  具体到特定的物理文件

  二、 索引的概念

  1、 类似书的目录结构

  2、 Oracle 的“索引”对象,与表关联的可选对象,提高SQL查询语句的速度

  3、 索引直接指向包含所查询值的行的位置,减少磁盘I/O

  4、 与所索引的表是相互独立的物理结构

  5、 Oracle 自动使用并维护索引,插入、删除、更新表后,自动更新索引

  6、 语法:CREATE INDEX index ON table (column[, column]...);

  7、 B-tree结构(非bitmap):

  [一]了解索引的工作原理:

  表:emp

  mysql 目录建立规则

  目标:查询Frank的工资salary

  建立索引:create index emp_name_idx on emp(name);
?

mysql 目录建立规则

 

mysql 目录建立规则
 [试验]测试索引的作用:

  1. 运行/rdbms/admin/utlxplan 脚本

  2. 建立测试表

  create table t as select * from dba_objects;

  insert into t select * from t;

  create table indextable

  as select rownum id,owner,object_name,subobject_name,

  object_id,data_object_id,object_type,created

  from t;

  3. set autotrace trace explain

  4. set timing on

  5. 分析表,可以得到cost

  6. 查询 object_name=’DBA_INDEXES’

  7. 在object_name列上建立索引

  8. 再查询

三、 唯一索引

  1、 何时创建:当某列任意两行的值都不相同

  2、 当建立Primary Key(主键)或者Unique constraint(唯一约束)时,唯一索引将被自动建立

  3、 语法:CREATE UNIQUE INDEX index ON table (column);

  4、 演示

  四、 组合索引

  1、 何时创建:当两个或多个列经常一起出现在where条件中时,则在这些列上同时创建组合索引

  2、 组合索引中列的顺序是任意的,也无需相邻。但是建议将最频繁访问的列放在列表的最前面

  3、 演示(组合列,单独列)

  五、 位图索引

  1、 何时创建:

  列中有非常多的重复的值时候。例如某列保存了 “性别”信息。

  Where 条件中包含了很多OR操作符。

  较少的update操作,因为要相应的跟新所有的bitmap

  2、 结构:位图索引使用位图作为键值,对于表中的每一数据行位图包含了TRUE(1)、FALSE(0)、或NULL值。

  3、 优点:位图以一种压缩格式存放,因此占用的磁盘空间比标准索引要小得多

  4、 语法:CREATE BITMAP INDEX index ON table (column[, column]...);

  5、 掩饰:

  create table bitmaptable as select * from indextable where owner in('SYS','PUBLIC');

  分析,查找,建立索引,查找

  六、 基于函数的索引

  1、 何时创建:在WHERE条件语句中包含函数或者表达式时

  2、 函数包括:算数表达式、PL/SQL函数、程序包函数、SQL函数、用户自定义函数。

  3、 语法:CREATE INDEX index ON table (FUNCTION(column));

  4、 演示

  必须要分析表,并且query_rewrite_enabled=TRUE

  或者使用提示/*+ INDEX(ic_index)*/

 七、 反向键索引

  目的:比如索引值是一个自动增长的列:

mysql 目录建立规则

  多个用户对集中在少数块上的索引行进行修改,容易引起资源的争用,比如对数据块的等待。此时建立反向索引。

  性能问题:

  语法:

  重建为标准索引:反之不行

  八、 键压缩索引

  比如表landscp的数据如下:

  site feature job

  Britten Park, Rose Bed 1, Prune

  Britten Park, Rose Bed 1, Mulch

  Britten Park, Rose Bed 1,Spray

  Britten Park, Shrub Bed 1, Mulch

  Britten Park, Shrub Bed 1, Weed

  Britten Park, Shrub Bed 1, Hoe

  ……

  查询时,以上3列均在where条件中同时出现,所以建立基于以上3列的组合索引。但是发现重复值很多,所以考虑压缩特性。

  Create index zip_idx

  on landscp(site, feature, job)

  compress 2;

  将索引项分成前缀(prefix)和后缀(postfix)两部分。前两项被放置到前缀部分。

  Prefix 0: Britten Park, Rose Bed 1

  Prefix 1: Britten Park, Shrub Bed 1

  实际所以的结构为:

  0 Prune

  0 Mulch

  0 Spray

  1 Mulch

  1 Weed

  1 Hoe

  特点:组合索引的前缀部分具有非选择性时,考虑使用压缩。减少I/O,增加性能。

  九、 索引组织表(IOT)

  将表中的数据按照索引的结构存储在索引中,提高查询速度。

  牺牲插入更新的性能,换取查询性能。通常用于数据仓库,提供大量的查询,极少的插入修改工作。

  必须指定主键。插入数据时,会根据主键列进行B树索引排序,写入磁盘。

  十、 分区索引

  簇:

  A cluster is a group of tables that share the same data blocks because they share common columns and are often used together.

mysql 目录建立规则

?

====================================================================================================================================

?

为什么要创建索引呢?这是因为,创建索引可以大大提高系统的性能。?
第一,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。?
第二,可以大大加快?数据的检索速度,这也是创建索引的最主要的原因。?
第三,可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。?
第四,在使用分组和排序?子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。?
第五,通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。?

也许会有人要问:增加索引有如此多的优点,为什么不对表中的每一个列创建一个索引呢?这种想法固然有其合理性,然而也有其片面性。虽然,索引有许多优点,?但是,为表中的每一个列都增加索引,是非常不明智的。这是因为,增加索引也有许多不利的一个方面。?

第一,创建索引和维护索引要耗费时间,这种时间随着数据?量的增加而增加。?
第二,索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大。?
第三,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。?

索引是建立在数据库表中的某些列的上面。因此,在创建索引的时候,应该仔细考虑在哪些列上可以创建索引,在哪些列上不能创建索引。一般来说,应该在这些列?上创建索引,例如:?

在经常需要搜索的列上,可以加快搜索的速度;?
在作为主键的列上,强制该列的唯一性和组织表中数据的排列结构;?
在经常用在连接的列上,这?些列主要是一些外键,可以加快连接的速度;?
在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的;?
在经常需要排序的列上创?建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间;?
在经常使用在WHERE子句中的列上面创建索引,加快条件的判断速度。?


同样,对于有些列不应该创建索引。一般来说,不应该创建索引的的这些列具有下列特点:?

第一,对于那些在查询中很少使用或者参考的列不应该创建索引。这是因?为,既然这些列很少使用到,因此有索引或者无索引,并不能提高查询速度。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求。?
第二,对于那?些只有很少数据值的列也不应该增加索引。这是因为,由于这些列的取值很少,例如人事表的性别列,在查询的结果中,结果集的数据行占了表中数据行的很大比?例,即需要在表中搜索的数据行的比例很大。增加索引,并不能明显加快检索速度。?
第三,对于那些定义为text,?image和bit数据类型的列不应该增加索引。这是因为,这些列的数据量要么相当大,要么取值很少。?
第四,当修改性能远远大于检索性能时,不应该创建索?引。这是因为,修改性能和检索性能是互相矛盾的。当增加索引时,会提高检索性能,但是会降低修改性能。当减少索引时,会提高修改性能,降低检索性能。因?此,当修改性能远远大于检索性能时,不应该创建索引。?

创建索引的方法和索引的特征?
创建索引的方法?
创建索引有多种方法,这些方法包括直接创建索引的方法和间接创建索引的方法。直接创建索引,例如使用CREATE?INDEX语句或者使用创建索引向导,间接创建索引,例如在表中定义主键约束或者唯一性键约束时,同时也创建了索引。虽然,这两种方法都可以创建索引,但是,它们创建索引的具体内容是有区别的。?
使用CREATE?INDEX语句或者使用创建索引向导来创建索引,这是最基本的索引创建方式,并且这种方法最具有柔性,可以定制创建出符合自己需要的索引。在使用这种方式创建索引时,可以使用许多选项,例如指定数据页的充满度、进行排序、整理统计信息等,这样可以优化索引。使用这种方法,可以指定索引的类型、唯一性和复合性,也就是说,既可以创建聚簇索引,也可以创建非聚簇索引,既可以在一个列上创建索引,也可以在两个或者两个以上的列上创建索引。?

通过定义主键约束或者唯一性键约束,也可以间接创建索引。主键约束是一种保持数据完整性的逻辑,它限制表中的记录有相同的主键记录。在创建主键约束时,系统自动创建了一个唯一性的聚簇索引。虽然,在逻辑上,主键约束是一种重要的结构,但是,在物理结构上,与主键约束相对应的结构是唯一性的聚簇索引。换句话说,在物理实现上,不存在主键约束,而只存在唯一性的聚簇索引。同样,在创建唯一性键约束时,也同时创建了索引,这种索引则是唯一性的非聚簇索引。因此,当使用约束创建索引时,索引的类型和特征基本上都已经确定了,由用户定制的余地比较小。?

当在表上定义主键或者唯一性键约束时,如果表中已经有了使用CREATE?INDEX语句创建的标准索引时,那么主键约束或者唯一性键约束创建的索引覆盖以前创建的标准索引。也就是说,主键约束或者唯一性键约束创建的索引的优先级高于使用CREATE?INDEX语句创建的索引。?

索引的特征?
索引有两个特征,即唯一性索引和复合索引。?
唯一性索引保证在索引列中的全部数据是唯一的,不会包含冗余数据。如果表中已经有一个主键约束或者唯一性键约束,那么当创建表或者修改表时,SQL?Server自动创建一个唯一性索引。然而,如果必须保证唯一性,那么应该创建主键约束或者唯一性键约束,而不是创建一个唯一性索引。当创建唯一性索引时,应该认真考虑这些规则:当在表中创建主键约束或者唯一性键约束时,SQL?Server自动创建一个唯一性索引;如果表中已经包含有数据,那么当创建索引时,SQL?Server检查表中已有数据的冗余性;每当使用插入语句插入数据或者使用修改语句修改数据时,SQL?Server检查数据的冗余性:如果有冗余值,那么SQL?Server取消该语句的执行,并且返回一个错误消息;确保表中的每一行数据都有一个唯一值,这样可以确保每一个实体都可以唯一确认;只能在可以保证实体完整性的列上创建唯一性索引,例如,不能在人事表中的姓名列上创建唯一性索引,因为人们可以有相同的姓名。?

复合索引就是一个索引创建在两个列或者多个列上。在搜索时,当两个或者多个列作为一个关键值时,最好在这些列上创建复合索引。当创建复合索引时,应该考虑这些规则:最多可以把16个列合并成一个单独的复合索引,构成复合索引的列的总长度不能超过900字节,也就是说复合列的长度不能太长;在复合索引中,所有的列必须来自同一个表中,不能跨表建立复合列;在复合索引中,列的排列顺序是非常重要的,因此要认真排列列的顺序,原则上,应该首先定义最唯一的列,例如在(COL1,COL2)上的索引与在(COL2,COL1)上的索引是不相同的,因为两个索引的列的顺序不同;为了使查询优化器使用复合索引,查询语句中的WHERE子句必须参考复合索引中第一个列;当表中有多个关键列时,复合索引是非常有用的;使用复合索引可以提高查询性能,减少在一个表中所创建的索引数量。


---

索引的类型?
根据索引的顺序与数据表的物理顺序是否相同,可以把索引分成两种类型。一种是数据表的物理顺序与索引顺序相同的聚簇索引,另一种是数据表的物理顺序与索引顺序不相同的非聚簇索引。?

聚簇索引的体系结构?
索引的结构类似于树状结构,树的顶部称为叶级,树的其它部分称为非叶级,树的根部在非叶级中。同样,在聚簇索引中,聚簇索引的叶级和非叶级构成了一个树状结构,索引的最低级是叶级。在聚簇索引中,表中的数据所在的数据页是叶级,在叶级之上的索引页是非叶级,索引数据所在的索引页是非叶级。在聚簇索引中,数据值的顺序总是按照升序排列。?

应该在表中经常搜索的列或者按照顺序访问的列上创建聚簇索引。当创建聚簇索引时,应该考虑这些因素:每一个表只能有一个聚簇索引,因为表中数据的物理顺序只能有一个;表中行的物理顺序和索引中行的物理顺序是相同的,在创建任何非聚簇索引之前创建聚簇索引,这是因为聚簇索引改变了表中行的物理顺序,数据行按照一定的顺序排列,并且自动维护这个顺序;关键值的唯一性要么使用UNIQUE关键字明确维护,要么由一个内部的唯一标识符明确维护,这些唯一性标识符是系统自己使用的,用户不能访问;聚簇索引的平均大小大约是数据表的百分之五,但是,实际的聚簇索引的大小常常根据索引列的大小变化而变化;在索引的创建过程中,SQL?Server临时使用当前数据库的磁盘空间,当创建聚簇索引时,需要1.2倍的表空间的大小,因此,一定要保证有足够的空间来创建聚簇索引。?

当系统访问表中的数据时,首先确定在相应的列上是否存在有索引和该索引是否对要检索的数据有意义。如果索引存在并且该索引非常有意义,那么系统使用该索引访问表中的记录。系统从索引开始浏览到数据,索引浏览则从树状索引的根部开始。从根部开始,搜索值与每一个关键值相比较,确定搜索值是否大于或者等于关键值。这一步重复进行,直到碰上一个比搜索值大的关键值,或者该搜索值大于或者等于索引页上所有的关键值为止。?

非聚簇索引的体系结构?
非聚簇索引的结构也是树状结构,与聚簇索引的结构非常类似,但是也有明显的不同。?
在非聚簇索引中,叶级仅包含关键值,而没有包含数据行。非聚簇索引表示行的逻辑顺序。?非聚簇索引有两种体系结构:一种体系结构是在没有聚簇索引的表上创建非聚簇索引,另一种体系结构是在有聚簇索引的表上创建非聚簇索引。?

如果一个数据表中没有聚簇索引,那么这个数据表也称为数据堆。当非聚簇索引在数据堆的顶部创建时,系统使用索引页中的行标识符指向数据页中的记录。行标识符存储了数据所在位置的信息。数据堆是通过使用索引分配图(IAM)页来维护的。IAM页包含了数据堆所在簇的存储信息。在系统表sysindexes?中,有一个指针指向了与数据堆相关的第一个IAM页。系统使用IAM页在数据堆中浏览和寻找可以插入新的记录行的空间。这些数据页和在这些数据页中的记录没有任何的顺序并且也没有链接在一起。在这些数据页之间的唯一的连接是IAM中记录的顺序。当在数据堆上创建了非聚簇索引时,叶级中包含了指向数据页的行标识符。行标识符指定记录行的逻辑顺序,由文件ID、页号和行ID组成。这些行的标识符维持唯一性。非聚簇索引的叶级页的顺序不同于表中数据的物理顺序。这些关键值在叶级中以升序维持。?

当非聚簇索引创建在有聚簇索引的表上的时候,系统使用索引页中的指向聚簇索引的聚簇键。聚簇键存储了数据的位置信息。如果某一个表有聚簇索引,那么非聚簇索引的叶级包含了映射到聚簇键的聚簇键值,而不是映射到物理的行标识符。当系统访问有非聚簇索引的表中数据时,并且这种非聚簇索引创建在聚簇索引上,那么它首先从非聚簇索引来找到指向聚簇索引的指针,然后通过使用聚簇索引来找到数据。?
当需要以多种方式检索数据时,非聚簇索引是非常有用的。当创建非聚簇索引时,要考虑这些情况:在缺省情况下,所创建的索引是非聚簇索引;在每一个表上面,可以创建不多于249个非聚簇索引,而聚簇索引最多只能有一个。?
系统如何访问表中的数据?
一般地,系统访问数据库中的数据,可以使用两种方法:表扫描和索引查找。第一种方法是表扫描,就是指系统将指针放置在该表的表头数据所在的数据页上,然后按照数据页的排列顺序,一页一页地从前向后扫描该表数据所占有的全部数据页,直至扫描完表中的全部记录。在扫描时,如果找到符合查询条件的记录,那么就将这条记录挑选出来。最后,将全部挑选出来符合查询语句条件的记录显示出来。第二种方法是使用索引查找。索引是一种树状结构,其中存储了关键字和指向包含关键字所在记录的数据页的指针。当使用索引查找时,系统沿着索引的树状结构,根据索引中关键字和指针,找到符合查询条件的的记录。最后,将全部查找到的符合查询语句条件的记录显示出来。?
在SQL?Server中,当访问数据库中的数据时,由SQL?Server确定该表中是否有索引存在。如果没有索引,那么SQL?Server使用表扫描的方法访问数据库中的数据。查询处理器根据分布的统计信息生成该查询语句的优化执行规划,以提高访问数据的效率为目标,确定是使用表扫描还是使用索引。?
索引的选项?
在创建索引时,可以指定一些选项,通过使用这些选项,可以优化索引的性能。这些选项包括FILLFACTOR选项、PAD_INDEX选项和SORTED_DATA_REORG选项。?
使用FILLFACTOR选项,可以优化插入语句和修改语句的性能。当某个索引页变满时,SQL?Server必须花费时间分解该页,以便为新的记录行腾出空间。使用FILLFACTOR选项,就是在叶级索引页上分配一定百分比的*空间,以便减少页的分解时间。当在有数据的表中创建索引时,可以使用FILLFACTOR选项指定每一个叶级索引节点的填充的百分比。缺省值是0,该数值等价于100。在创建索引的时候,内部索引节点总是留有了一定的空间,这个空间足够容纳一个或者两个表中的记录。在没有数据的表中,当创建索引的时候,不要使用该选项,因为这时该选项是没有实际意义的。另外,该选项的数值在创建时指定以后,不能动态地得到维护,因此,只应该在有数据的表中创建索引时才使用。?
PAD_INDEX?选项将FILLFACTOR选项的数值同样也用于内部的索引节点,使内部的索引节点的填充度与叶级索引的节点中的填充度相同。如果没有指定FILLFACTOR选项,那么单独指定PAD_INDEX选项是没有实际意义的,这是因为PAD_INDEX选项的取值是由FILLFACTOR选项的取值确定的。?
当创建聚簇索引时,SORTED_DATA_REORG选项清除排序,因此可以减少建立聚簇索引所需要的时间。当在一个已经变成碎块的表上创建或者重建聚簇索引时,使用SORTED_DATA_REORG选项可以压缩数据页。当重新需要在索引上应用填充度时,也使用该选项。当使用?SORTED_DATA_REORG选项时,应该考虑这些因素:SQL?Server确认每一个关键值是否比前一个关键值高,如果都不高,那么不能创建索引;SQL?Server要求1.2倍的表空间来物理地重新组织数据;使用SORTED_DATA_REORG选项,通过清除排序进程而加快索引创建进程;从表中物理地拷贝数据;当某一个行被删除时,其所占的空间可以重新利用;创建全部非聚簇索引;如果希望把叶级页填充到一定的百分比,可以同时使用?FILLFACTOR选项和SORTED_DATA_REORG选项。?
索引的维护?
为了维护系统性能,索引在创建之后,由于频繁地对数据进行增加、删除、修改等操作使得索引页发生碎块,因此,必须对索引进行维护。?
使用DBCC?SHOWCONTIG语句,可以显示表的数据和索引的碎块信息。当执行DBCC?SHOWCONTIG语句时,SQL?Server浏览叶级上的整个索引页,来确定表或者指定的索引是否严重碎块。DBCC?SHOWCONTIG语句还能确定数据页和索引页是否已经满了。当对表进行大量的修改或者增加大量的数据之后,或者表的查询非常慢时,应该在这些表上执行?DBCC?SHOWCONTIG语句。当执行DBCC?SHOWCONTIG语句时,应该考虑这些因素:当执行DBCC?SHOWCONTIG语句时,SQL?Server要求指定表的ID号或者索引的ID号,表的ID号或者索引的ID号可以从系统表sysindexes中得到;应该确定多长时间使用一次?DBCC?SHOWCONTIG语句,这个时间长度要根据表的活动情况来定,每天、每周或者每月都可以。?
使用DBCC?DBREINDEX语句重建表的一个或者多个索引。当希望重建索引和当表上有主键约束或者唯一性键约束时,执行DBCC?DBREINDEX语句。除此之外,执行DBCC?DBREINDEX语句还可以重新组织叶级索引页的存储空间、删除碎块和重新计算索引统计。当使用执行DBCC?DBREINDEX语句时,应该考虑这些因素:根据指定的填充度,系统重新填充每一个叶级页;使用DBCC?DBREINDEX语句重建主键约束或者唯一性键约束的索引;使用SORTED_DATA_REORG选项可以更快地创建聚簇索引,如果没有排列关键值,那么不能使用DBCC?DBREINDEX语句;DBCC?DBREINDEX语句不支持系统表。另外,还可以使用数据库维护规划向导自动地进行重建索引的进程。?
统计信息是存储在SQL?Server中的列数据的样本。这些数据一般地用于索引列,但是还可以为非索引列创建统计。SQL?Server维护某一个索引关键值的分布统计信息,并且使用这些统计信息来确定在查询进程中哪一个索引是有用的。查询的优化依赖于这些统计信息的分布准确度。查询优化器使用这些数据样本来决定是使用表扫描还是使用索引。当表中数据发生变化时,SQL?Server周期性地自动修改统计信息。索引统计被自动地修改,索引中的关键值显著变化。统计信息修改的频率由索引中的数据量和数据改变量确定。例如,如果表中有10000行数据,1000行数据修改了,那么统计信息可能需要修改。然而,如果只有50行记录修改了,那么仍然保持当前的统计信息。除了系统自动修改之外,用户还可以通过执行UPDATE?STATISTICS语句或者sp_updatestats系统存储过程来手工修改统计信息。使用UPDATE?STATISTICS语句既可以修改表中的全部索引,也可以修改指定的索引。?
使用SHOWPLAN和STATISTICS?IO语句可以分析索引和查询性能。使用这些语句可以更好地调整查询和索引。SHOWPLAN语句显示在连接表中使用的查询优化器的每一步以及表明使用哪一个索引访问数据。使用SHOWPLAN语句可以查看指定查询的查询规划。当使用SHOWPLAN语句时,应该考虑这些因素。SET?SHOWPLAN_ALL语句返回的输出结果比SET?SHOWPLAN_TEXT语句返回的输出结果详细。然而,应用程序必须能够处理SET?SHOWPLAN_ALL语句返回的输出结果。SHOWPLAN语句生成的信息只能针对一个会话。如果重新连接SQL?Server,那么必须重新执行SHOWPLAN语句。STATISTICS?IO语句表明输入输出的数量,这些输入输出用来返回结果集和显示指定查询的逻辑的和物理的I/O的信息。可以使用这些信息来确定是否应该重写查询语句或者重新设计索引。使用STATISTICS?IO语句可以查看用来处理指定查询的I/O信息。?
就象SHOWPLAN语句一样,优化器隐藏也用来调整查询性能。优化器隐藏可以对查询性能提供较小的改进,并且如果索引策略发生了改变,那么这种优化器隐藏就毫无用处了。因此,限制使用优化器隐藏,这是因为优化器隐藏更有效率和更有柔性。当使用优化器隐藏时,考虑这些规则:指定索引名称、当?index_id为0时为使用表扫描、当index_id为1时为使用聚簇索引;优化器隐藏覆盖查询优化器,如果数据或者环境发生了变化,那么必须修改优化器隐藏。