SQL学习之路(二)——索引
索引时一个单独的、物理的数据库结构,是数据库的一个表中所包含的值的列表,其注明了表的各个值所在的存储位置。索引时依赖于表建立的,提供了编排表中数据的方法。
实际上,一个表的存储时由两个部分组成的,一部分用来存放表的数据页面,另一部分存放索引页面,索引就存放在索引页面上。通常,索引页面相对于数据页面来说小得多。当进行数据检索时,系统先搜索索引页面,从中找到所需数据的指针,再通过指针从数据页面中读取数据。
某种程度上,可以把数据库看作一本书,把索引看作书的目录,通过目录查找书中的信息。显然,与没有目录的书相比,显得方便和快捷。
首先创建三个表
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
代码
CREATE TABLE StudentInfo
(
sno char(3) NOT NULL,
sname char(8) NOT NULL,
sex char(2) NOT NULL,
addreaa char(8) NOT NULL,
dno int NOT null
)
INSERT INTO StudentInfo VALUES('001','张平1','女','湖南',2)
INSERT INTO StudentInfo VALUES('002','张平2','女','北京',2)
INSERT INTO StudentInfo VALUES('003','张平3','女','湖北',1)
INSERT INTO StudentInfo VALUES('004','张平4','女','浙江',2)
INSERT INTO StudentInfo VALUES('005','张平5','女','山东',4)
INSERT INTO StudentInfo VALUES('006','张平6','女','山东',3)
INSERT INTO StudentInfo VALUES('007','张平7','女','河北',3)
INSERT INTO StudentInfo VALUES('008','张平8','女','河南',1)
INSERT INTO StudentInfo VALUES('009','张平9','女','山西',3)
INSERT INTO StudentInfo VALUES('010','张平10','女','陕西',4)
CREATE TABLE RecruitInfo
(
address char(10) NOT NULL,
score float NOT NULL,
snum int NOT NULL
)
INSERT INTO RecruitINfo VALUES('北京',560,220)
INSERT INTO RecruitINfo VALUES('湖南',648.5,65)
INSERT INTO RecruitINfo VALUES('湖北',654,85)
INSERT INTO RecruitINfo VALUES('山东',650,80)
INSERT INTO RecruitINfo VALUES('浙江',638,76)
INSERT INTO RecruitINfo VALUES('河南',639.5,72)
INSERT INTO RecruitINfo VALUES('河北',625,58)
INSERT INTO RecruitINfo VALUES('山西',631,55)
INSERT INTO RecruitINfo VALUES('陕西',635,62)
CREATE TABLE Department
(
dno int NOT NULL,
dname char(20) NOT NULL,
dnum int NOT NULL
)
INSERT INTO Department VALUES(1,'计算机工程系',220)
INSERT INTO Department VALUES(2,'汽车系',80)
INSERT INTO Department VALUES(3,'机械工程系',120)
INSERT INTO Department VALUES(4,'电子工程系',180)
INSERT INTO Department VALUES(5,'工程物理系',40)
INSERT INTO Department VALUES(6,'应用数学系',50)
INSERT INTO Department VALUES(7,'材料工程系',60)
编写SELECT * FROM StudentInfo得到以下结果
然后来看看非聚集索引
基本创建语法:
--创建非聚集索引
CREATE INDEX Name_Index
ON StudentInfo(sname)
下面看看创建非聚集索引之后的查询
SELECT * FROM StudentInfo
结果如下所示:
![](https://pic002.cnblogs.com/images/2010/150237/2010102119563963.jpg)
可以发现结果和先前未创建非聚集索引以前是一样的结果,为什么会这样呢?
因为非聚集索引并不会讲数据库中的数据重新排序。
如果想看非聚集索引的效果,可以强制使用非聚集索引
--查询时强制使用非聚集索引
SELECT * FROM StudentInfo WITH (INDEX (Name_Index))
接下来,看看如何构建唯一的非聚集索引
--创建唯一非聚集索引
CREATE UNIQUE INDEX Sno_Index ON StudentInfo(sno DESC)
当你再试图像表中插入有相同学号的记录时就会跑出异常了
INSERT StudentInfo VALUES('006','刘备','男','河南',1)
消息 2601,级别 14,状态 1,第 1 行
不能在具有唯一索引 'Sno_Index' 的对象 'dbo.StudentInfo' 中插入重复键的行。
语句已终止。
下面看看聚集索引
1:聚集索引一个表中只能存在一个
2:使用聚集索引将占用最小的磁盘空间,因为DBMS在插入新行时,会自动重用以前非配给删除的空间
3:不再需要order by 语句
聚集索引的创建语句比非聚集的多了一个Clustered关键字
--创建聚集索引
CREATE CLUSTERED INDEX SnameClustered_Index ON StudentInfo (sname)
SELECT * FROM StudentInfo得到的结果如下:
发现数据表中的数据已经拍过序了。。。说明聚集索引会对数据表中的内容进行一个重排
另外,创建多字段的聚集索引也是非常有用的,有时候你需要依据两个字段去查询记录
CREATE CLUSTERED INDEX SexAddreaaClustered_Index ON StudentInfo(sex,addreaa)
对于索引的销毁,采用Drop关键字
DROP INDEX studentinfo.Sno_Index
但是要特别注意的是,必须在索引前面带上table的名字
最后,说几点使用索引的几点原则:
1.对于小的数据表,使用索引并不能提高任何检索性能,因此不需要对其创建索引
2.当用户要检索的字段的数据包含很多数值或很多空值NULL时,为该字段创建索引会大大提高检索效率
3.当用户查询表中的数据时,如果查询结果包含的数据行较少,一般少于数据总数的25%时,使用索引会显著提高查询效率。反之,索引用户不大
4.索引应该经常在where子句中使用,否则,该索引就没有发生作用
5.建表时,先装数据,再建索引
6.在对数据表进行大量更新时,最好先销毁索引,等数据更新完毕后再创建索引,这样会提高效率。(因为索引会降低数据更新的效率)
7.如果可能,把数据表和索引存放于不同的磁盘上,这样会提高查询效率(这一点,我还不知道如何弄)