数据库:索引

索引的作用

是什么

“索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息。” 看中心语-关键词[一种结构],说到底索引就是对数据列的值进行结构化排序的一个东西.

索引属于物理存储的路径概念,而不是逻辑概念。在执行一个查询时,系统会自动选择合适的索引作为数据存取路径,用户不必也不能选择索引。

目的

加快查询速度

谁可以建立索引

DBA或 建表人

DBMS一般会自动建立以下列上的索引:

primary keyunique

谁维护

DBMS自动完成

是否使用索引

DBMS自动选择是否使用索引以及使用哪些索引

索引的优点

1、可以加快有连接表、排序或分组操作的查询的速度

2、若创建了唯一索引,可强制值的唯一性

3、索引的创建和维护是升序或降序的

4、索引最好创建在具有高度选择性的列上,即列或列组合的值大部分是唯一的

索引的缺点

1、增加了数据库的存储空间

【我们假设在一张表中的一条记录在磁盘上占用1KB话,我们对其中10B的一个字段建立索引,那么该记录对应的索引块的大小只有10B,如果一张表的的数据量比较大,大约100,000条,那么用来存储索引耗费的空间就是100,000X10B=1000,000B=10000KB=1MB,换句话说,这张白表也因为这个索引的建立而多使用了大约1MB的存储空间,当然对与大批量数据来说,这么点空间是不足为道的。但事实是,索引确实耗费了更多空间;】

2、在插入和修改数据时要花费较多的时间(因为索引也要随之变动);

还有就是,对某些场景下,数据量不是特别大的情况下,对于某些添加索引的行为,不但不能优化查询速度,反而会减慢查询速度,当然,如果索引的建立不恰当,所选择建立索引的字段不合适,也可能会削弱查询速度,当然在数据量不大的情况下,基于SQL服务器本身强大的处理能力,这种削弱表现是非常微弱的,但是一旦数据量大起来,原本可以不需要考虑索引就能很快查询出来数据的,结果因为添加了索引反而加重了查询数据的消耗,不恰当的索引方式造成的影响就会表现的很明显;
所以,索引不是万能的,某些情况下,添加索引可能比不添加索引更慢!

索引的工作方式

 索引类型

1、聚簇索引

为了提高某个属性的查询速度,把这个或这些属性上具有相同值的元组集中存放在连续的物理块中称为 “聚簇”,该属性称为“聚簇码”

【平时习惯逛图书馆的童鞋可能比较清楚,如果你要去图书馆借一本书,最开始是去电脑里面查书名然后根据书名来定位藏书在那个区,哪个书柜,哪一行,第多少本。。。清晰明确,一目了然,因为藏书的结构与图书室的位置,书架的顺序,书本的摆放顺序与书籍的编号都是从大到小一致的顺序摆放的,所以很容易找到。比如,你的目标藏书在C区2柜3排5仓,那么你走到B区你就很快知道前面就快到了C区了,你直接奔着2柜区就能找到了。 这就是雷同于聚簇索引的功效了】

记录的索引顺序与物理顺序相同。显然,一个表只能包含一个聚簇索引(如主键列)。在聚簇索引下,因为其物理存储的特征,可以避免大范围的数据扫描(尤其是有重复的索引列值进行范围查询时),因此它有更快的数据访问速度。

2、非聚簇索引

【同样的,如果你去的不是图书馆,而是某城市的商业性质的图书城,那么你想找的书就摆放比较随意了,由于商业图书城空间比较紧正,藏书通常按照藏书上架的先后顺序来摆放的,所以如果查询到某书籍放在C区2柜3排5仓,但你可能要绕过F区,而不是A.B.C.D…连贯一致的,也可能同在C区的2柜,书柜上第一排是计算机类的书记,也可能最后一排就是医学类书籍;】

记录的索引顺序与物理顺序没有必然关系。非聚簇索引不重新组织表中数据的顺序,一个表可以有多个非聚簇索引,每一个都提供访问数据的不同排序顺序。创建时若未指定索引类型,则默认为非聚簇索引。

3、唯一索引

 不允许其中任何两行具有相同索引值的索引。数据库可能会阻止表中创建重复键值的新数据。键值的惟一性通过 UNIQUE 关键字显式维护,或通过一个内部的对用户不可见的惟一标识符隐式维护,常将唯一值的列创建为聚簇索引。 

索引的使用

建立原则

(1)索引由DBA和DBO(表的属主)负责建立于删除,由DBMS自动维护。

(2)大表应建索引,小表不必建索引。不宜建较多索引。没用的索引及时删除。

(3)根据查询要求建立索引,对于查询频度高,实时性高的数据一定要建索引。在查询中不常被引用的列不要建立索引。

(4)主键列默认自动建立聚簇索引

(5)外键列、或在表连接操作中经常用到的列建立索引,可加快连接查询的速度。

(6)常被搜索键值范围的列建立索引,如条件“sage between 18 and 20”,建议对sage列建立索引。

(7)常以排序形式访问的列建立索引,如在order by字后出现的列。

(8)常在聚集操作中处于同一组的列建立索引,如在group by字后出现的列。

建立索引

语句格式 :CREATE [UNIQUE] [CLUSTERED(聚簇索引)/ NONCLUSTERED(非聚簇索引) ] INDEX <索引名> ON <表名>(<列名>[<次序>][,<列名>[<次序>] ]…);

[例] 在Student表的Sname(姓名)列上建立一个聚簇索引。

CREATE CLUSTERED INDEX Stusname ON Student(Sname);

[例] 为学生-课程数据库中的Student,Course,SC三个表建立索引。其中Student表按学号升序建唯一索引,Course表按课程号升序建唯一索引,SC表按学号升序和课程号降序建唯一索引

CREATE UNIQUE INDEX Stusno ON Student(Sno);

CREATE UNIQUE INDEX Coucno ON Course(Cno);

CREATE UNIQUE INDEX SCno ON SC(Sno ASC,Cno DESC);

删除索引

索引建立后,由系统来选择和维护,用户无权干预。但有些索引的维护反而加重了系统的负担,就不得不将其删除。

语法格式: DROP INDEX <表名.索引名>;

由于不同的表可能建立了名字相同的索引,所以在删除索引时要求索引名前必须有表名做前缀。删除索引时,系统会从数据字典中删去有关该索引的描述。

[例] 删除Student表的Stusname索引

DROP INDEX student.Stusname;

参考:

[1]   和刚入门的菜鸟们聊聊–什么是聚簇索引与非聚簇索引