陋室铭
永远也不要停下学习的脚步(大道至简至易)

一、索引的概念

索引就是加快检索表中数据的方法。数据库的索引类似于书籍的索引。在书籍中,索引允许用户不必翻阅完整个书就能迅速地找到所需要的信息。在数据库中,索引也允许数据库程序迅速地找到表中的数据,而不必扫描整个数据库。
(正常没有检索的话 在表里找数据,是要在所有数据中找 符合条件的数据,有索引的话,直接根据索引能找到符合条件的数据 而不必在所有数据里找)(他并不是提高了数据库检索速度,而是定义好了一个目录,所以索引键的设定是选择最适合做索引内容的字段,一般为查询条件,它实际就是象一本书的目录中的一条总结性语言作为目录指定页数,也就是说,如果查找的内容和目录无关,那他就失去作用了)

二、索引的特点

1.索引可以加快数据库的检索速度

2.索引降低了数据库插入、修改、删除等维护任务的速度

3.索引创建在表上,不能创建在视图上

4.索引既可以直接创建,也可以间接创建

5.可以在优化隐藏中,使用索引

6.使用查询处理器执行SQL语句,在一个表上,一次只能使用一个索引

7.其他

三、索引的优点

1.创建唯一性索引,保证数据库表中每一行数据的唯一性

2.大大加快数据的检索速度,这也是创建索引的最主要的原因

3.加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。

4.在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。

5.通过使用索引,可以在查询的过程中使用优化隐藏器,提高系统的性能。

四、索引的缺点

1.创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加

2.索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大

3.当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,降低了数据的维护速度

五、索引分类

1.直接创建索引和间接创建索引

直接创建索引: CREATE INDEX mycolumn_index ON mytable (myclumn)

间接创建索引:定义主键约束或者唯一性键约束,可以间接创建索引

2.普通索引和唯一性索引

普通索引:

CREATE INDEX mycolumn_index ON mytable (myclumn)

唯一性索引:保证在索引列中的全部数据是唯一的,对聚簇索引和非聚簇索引都可以使用

 

CREATE UNIQUE COUSTERED INDEX myclumn_cindex ON mytable(mycolumn)

3.单个索引和复合索引

单个索引:即非复合索引

复合索引:又叫组合索引,在索引建立语句中同时包含多个字段名,最多16个字段

 

CREATE INDEX name_index ON username(firstname,lastname)

4.聚簇索引和非聚簇索引(聚集索引,群集索引)

聚簇索引:物理索引,与基表的物理顺序相同,数据值的顺序总是按照顺序排列

CREATE CLUSTERED INDEX mycolumn_cindex ON mytable(mycolumn) WITH

ALLOW_DUP_ROW(允许有重复记录的聚簇索引)

非聚簇索引:

 

CREATE UNCLUSTERED INDEX mycolumn_cindex ON mytable(mycolumn)

六、索引的使用

1.当字段数据更新频率较低,查询使用频率较高并且存在大量重复值是建议使用聚簇索引

2.经常同时存取多列,且每列都含有重复值可考虑建立组合索引

3.复合索引的前导列一定好控制好,否则无法起到索引的效果。如果查询时前导列不在查询条件中则该复合索引不会被使用。前导列一定是使用最频繁的列

4.多表操作在被实际执行前,查询优化器会根据连接条件,列出几组可能的连接方案并从中找出系统开销最小的最佳方案。连接条件要充份考虑带有索引的表、行数多的表;内外表的选择可由公式:外层表中的匹配行数*内层表中每一次查找的次数确定,乘积最小为最佳方案

5.where子句中对列的任何操作结果都是在sql运行时逐列计算得到的,因此它不得不进行表搜索,而没有使用该列上面的索引;如果这些结果在查询编译时就能得到,那么就可以被sql优化器优化,使用索引,避免表搜索。

例:

 

select * from record where substring(card_no,1,4)=’5378’
            && select * from record where card_no like ’5378%’

任何对列的操作都将导致表扫描,它包括数据库函数、计算表达式等等,查询时要尽可能将操作移至等号右边

6.where条件中的’in’在逻辑上相当于’or’,所以语法分析器会将in ('0','1')转化为column='0' or column='1'来执行。我们期望它会根据每个or子句分别查找,再将结果相加,这样可以利用column上的索引;但实际上它却采用了"or策略",即先取出满足每个or子句的行,存入临时数据库的工作表中,再建立唯一索引以去掉重复行,最后从这个临时表中计算结果。因此,实际过程没有利用column上索引,并且完成时间还要受tempdb数据库性能的影响。in、or子句常会使用工作表,使索引失效;如果不产生大量重复值,可以考虑把子句拆开;拆开的子句中应该包含索引

7.要善于使用存储过程,它使sql变得更加灵活和高效

 

“聚集索引”与“非聚集索引”的理解很简单:“聚集索引”就是物理上的排列方式,而“非聚集索引”是使用索引表(相当于书的目录),使用索引之所以能提高性能,也就是“避免全表扫描”。
 因此一个表只能有一个“聚集索引”,因为在物理上,不可能会有“两种”物理存放方式吧。也真是如此“聚集索引”对查询性能的影响最大,所以要非常注意“聚集索引”的建立,我目前意识到、也是Freedk所推荐的“单据日期”作为聚集索引,我说的“单据日期”是指日常业务性的记录,一般都是会有一个日期字段的,而80%查询中都会用到此"日期字段",而且把它放在Where的第一个效果最佳,因为会在指定的区域内进行其他条件的查询,范围少了很多很多,性能效果提高明显。 
 至于其他的索引,这只要根据业务的需要,对于一些会进行查询的字段进行一定的索引,也就是尽可能的“避免全表扫描”就可以提高系统性能。当然过多的索引也会引起系统负担,想想要建那么多“目录”自然会增加负担了。
 还有“聚集索引”由于是物理存储的,性能上固然是提高了,但对于插入与删除,会引起数据的“移动”(在中间插入一条记录,会引起后半部分记录的后移),当然数据库有自己的存储机制,会采用“页”来进行分块存储,可以避免一定的“移动”,所以“聚集索引”最好是在“大部分”情况下可以“递增”,我们目前采用的“单据日期”也刚好是符合这个条件的。

聚集索引---(簇索引):

 

1.  一张表只能包含一个聚集索引;

2.  在聚集索引中,表中各行的物理顺序与键值的逻辑(索引)顺序相同;

3.  如果不是聚集索引,表中各行的物理顺序与键值的逻辑顺序不匹配。聚集索引比非聚集索引有更快的数据访问速度;

4.  聚集索引通常可加快    UPDATE    和    DELETE    操作的速度,因为这两个操作需要读取大量的数据;

5.  创建或修改聚集索引可能要花很长时间,因为执行这两个操作时要在磁盘上对表的行进行重组;                可考虑将聚集索引用于:         
1.  包含数量有限的唯一值的列,如    state    列只包含    50    个唯一的州代码。    
2.  使用下列运算符返回一个范围值的查询:BETWEEN、>、>=、<    和    <=。     
3.  返回大结果集的查询。       

创建聚集索引:     
1.  在数据库关系图中选择要创建索引的表,右击该表,然后从快捷菜单中选择"索引/键"命令。           
1'.  为要创建索引的表打开表设计器,在表设计器中右击,然后从快捷菜单中选择"索引/键"命令。     
2.  选择"创建为    CLUSTERED"复选框。当保存表或关系图时,索引即创建在数据库中。   
非聚集索引:   

1.  非聚集索引与课本中的索引类似。数据存储在一个地方,索引存储在另一个地方,索引带有指针指向数据的存储位置;

2.  索引中的项目按索引键值的顺序存储,而表中的信息按另一种顺序存储(这可以由聚集索引规定)

3.  如果在表中未创建聚集索引,则无法保证这些行具有任何特定的顺序。

可考虑将非聚集索引用于: 

1.  包含大量非重复值的列,如姓氏和名字的组合(如果聚集索引用于其它列)。如果只有很少的非重复值,如只有  1  和  0,则大多数查询将不使用索引,因为此时表扫描通常更有效。

2.  不返回大型结果集的查询。

3.  返回精确匹配的查询的搜索条件(WHERE  子句)中经常使用的列。

4.  经常需要联接和分组的决策支持系统应用程序。应在联接和分组操作中使用的列上创建多个非聚集索引,在任何外键列上创建一个聚集索引。

5.  在特定的查询中覆盖一个表中的所有列。这将完全消除对表或聚集索引的访问。 

 

索引很有用哟~

在查询成本中最好不要出现大于0.1的成本,如果出现大于1.0几的那就危险了~

posted on 2008-01-28 15:12  宏宇  阅读(541)  评论(1编辑  收藏  举报