SQL Server(二)-索引

 索引


索引是某个表中一列或多个列值的组合和相应的指向表中物理标识这些值的数据页的逻辑指针的清单。它就像书的目录,使得在数据库中,程序无须对整个表进行扫描,就可以快速地查找需要的数据。
  索引包含从表或视图中一个或多个列生成的,以及映射到指定数据的存储位置的指针索引需要占用数据库空间。它还可以强制数据具有唯一性,以保证数据完整性。
需要说明的是,虽然索引可以提高查询数据的效率,但是,当对相关数据做DML操作时,会引起相关的索引重建,重建索引需要时间,因此,过多的索引可能会增加数据库DML操作的时间,这里不建议对数据量小的表或数据改动频繁的表使用索引(除非有必要)。
 

在SQL Server中可以分为以下几种索引:
1.唯一索引
此类索引表示表中每一个索引值只对应唯一的相关数据,由于它和主键的功能类似,所以,唯一索引常用于主键列中。
2.聚集索引
它会根据聚集索引键的顺序来存储表或视图中的数据,即对表的物理数据按索引键值的顺序进行排序,然后再重新存储到磁盘上。聚集索引与数据是混为一体的,它的叶节点中存储的是实际的数据。类似电话薄,每个表只允许有一个聚集索引,但该索引可以包含多个列。聚集索引对搜索范围值的列特别有效。例如对日期列进行搜索可以利用聚集索引完成,它会快速地定位开始日期,然后对表中的相邻行进行索引,直到结束行。该类索引适用的情况主要有以下几种:
● 当利用BETWEEN,>,>=,<或<=返回一个范围值时。
● 含有大量的非重复值的列。
● 被访问的列是连续的。
● 经常被使用连接或GROUP BY子句的查询访问的列。

 

注意:定义聚集索引键时使用的列越少越好,否则将会很耗费磁盘空间。
3.非聚集索引
该索引中索引键值的顺序与磁盘上行的物理存储顺序不同。查询优化器在搜索数据值时,先搜索非聚集索引以找到数据值在表中的位置,然后直接从该位置检索数据。这使非聚集索引成为完全匹配查询的最佳选择,因为索引包含说明查询所搜索的数据值在表中的精确位置的项。
说明:当表中有被设置为唯一的列时,SQL Server会自动建立一个非聚集的唯一性索引。而当表中有主键约束时,SQL Server会在主键建立一个聚集索引。。
索引在数据库中发挥着重要的作用,主要表现在以下几个方面:
● 可以非常有效地提高检索数据的速度。
● 可以保证数据唯一性。
● 使用索引可以在检索数据的过程中使用优化隐藏器,提高系统性能。
● 可以减少查询中分组和排序的时间。
 --索引的创建
索引创建的关键语句是CREATE INDEX,其主要格式如下:

CREATE [ UNIQUE ] [ CLUSTERED|NONCLUSTERED ] INDEX index_name
ON table_or_view_name
( column [ ASC|DESC ] [ ,...n ] )
[with
[PAD_INDEX = { ON|OFF }]
[[,]FILLFACTOR=fillfactor][[,]IGNORE_DUP_KEY = { ON|OFF }]
[[,]DROP_EXISTING = { ON|OFF }]
    [[,]STATISTICS_NORECOMPUTE = { ON|OFF }]
[[,]SORT_IN_TEMPDB = { ON|OFF }]
]
[ ON filegroup ]


【语法说明】
● CREATE,INDEX:创建索引关键词。
● UNIQUE:表明该索引是唯一索引。唯一索引不允许两行具有相同的索引键值,视图的聚集索引必须唯一。
CLUSTERED:表示创建聚集索引。创建聚集索引时会重新生成表中现有的非聚集索引。如果没有指定CLUSTERED,则创建非聚集索引。
NONCLUSTERED:表示创建非聚集索引。每个表都最多可包含249个非聚集索引。
● index_name:表示索引的名称,索引名称要求在表或视图中必须唯一(数据库中不做要求)。
● column:为索引所作用的列,可以有多个。如果指定两个或多个列名,那么可以为指定列的组合值创建组合索引,同时可以在后面的括号中,按排序优先级列出组合索引中要包括的列。
● ASC|DESC:指定特定索引列的升序或降序排序方向,默认值为升序。
● PAD_INDEX:索引填充,默认为OFF。
● FILLFACTOR=fillfactor:定一个百分比,指示在创建或重新生成索引期间,数据库引擎对各索引页的叶级填充的程度。fillfactor必须为介于1至100之间的整数值。默认值为0。
● IGNORE_DUP_KEY:指定在插入操作尝试向唯一索引插入重复键值时的错误响应。
● DROP_EXISTING:指定应删除并重新生成已命名的先前存在的聚集或非聚集索引。默认值为OFF。
● STATISTICS_NORECOMPUTE:指定是否重新计算分发统计信息。默认值为OFF。
● SORT_IN_TEMPDB:指定是否在tempdb中存储临时排序结果。默认值为OFF。
● ON filegroup:用于指定存放索引的文件组。
下面的实例介绍了如何创建非聚集索引。为了方便讲解,首先创建表T_INDEX,并为其增加数据,创建脚本如下:

  CREATE TABLE [dbo].[Newuser](
       [Id] [int] IDENTITY(1,1) NOT NULL,
       [username] [nvarchar](50) NOT NULL,
       [password] [nvarchar](20) NOT NULL,
   CONSTRAINT [PK_Newuser] PRIMARY KEY CLUSTERED
  (
       [Id] ASC              --主键
  )WITH ( PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF,
           IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON,
           ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
  ) ON [PRIMARY]

添加数据后:



【例5.15】创建唯一非聚集索引。
要求对表Newuser中的列username创建唯一的非聚集索引,这样增加数据时,该列将不得出现重复数据,相关脚本如下:

USE Test
GO
CREATE UNIQUE INDEX IND_USERNAME
ON Newuser(username)


当执行以上脚本时,会提示成功,接下来可以对其进行验证,验证脚本如下:

  INSERT INTO Newuser
           (username,password)
      VALUES
           ('赵六', '111')
  GO


执行这段插入数据的脚本,此时由于表Newuser中的username列已经存在“赵六”的数据了,那么将提示出错。

注意:在已知表上创建唯一性索引的前提是,创建索引的列的现有记录不得重复,否则,创建不成功。
如果使用索引,则需要查询语句的WHERE子句包含索引列,本例中就是username列。而利用WITH关键词则可以强制使用指定的索引来查询数据。相关语法如下:

SELECT col1,col2,……
FROM table_name
WITH (INDEX (index_name))
WHERE condition


【语法说明】
● INDEX:表示强制使用索引。
● index_name:强制使用的索引名称。
 --强制使用索引。
要求强制使用索引IND_USERNAME对表Newuser进行数据查询,并和未强制使用索引IND_USERNAME时查询数据进行对比,相关脚本如下:

  --未强制使用索引
  SELECT Id, username, password
    FROM test.dbo.[Newuser]
  --强制使用索引
  SELECT Id, username, password
    FROM test.dbo.[Newuser]
    WITH (INDEX (IND_USERNAME))


【执行效果】
在查询窗口执行以上脚本,执行结果
从图可以看出,一旦强制使用索引,那么查询结果将按照索引列进行排序。
注意:如果查询表中的所有数据,那么使用索引没有意义。该例题只是为了演示索引的作用效果。

--索引的管理
索引同表或视图一样,都属于数据库的对象,作为一种数据库对象存在,允许对其进行查看、修改和删除等常用的操作。
1.查看索引
SQL Server中提供了一个系统存储过程sp_helpindex,利用它可以返回表的所有索引信息,其相关语法形式如下:
sp_helpindex [@objname=]'name'
语法中的[@objname=]'name'用于指定当前数据库中的表或视图的名称。
--查看表中的索引信息。
要求利用sp_helpindex存储过程,查看表Newuser中的索引信息,相关脚本如下:

  USE Test
  GO

  sp_helpindex Newuser

【执行效果】


index_name表示索引的名称;index_description则是对索引的说明,包括索引的类型、所在的文件组等;index_keys则是索引列名。
2.禁用索引
利用ALTER INDEX语句,可对索引禁用,相关语法如下:

ALTER INDEX index_name
ON table_or_view_name
DISABLE


禁用索引只是防止用户访问该索引,但索引的定义会继续保留在系统中。
--禁用IND_USERNAME索引。
IND_USERNAME索引作用的表为Newuser,相关脚本如下:

  ALTER INDEX IND_USERNAME
  ON Newuser
  DISABLE


执行脚本,成功后,可以利用以下的脚本进行验证:

SELECT Id, username, password
  FROM test.dbo.Newuser
  WITH (INDEX (IND_USERNAME))


执行结果


注意:如果为聚集索引,禁用索引后,用户将不能访问索引所在的基础表数据
对于已经禁用的索引,可以利用以下的脚本重新启用索引

ALTER INDEX IND_USERNAME
ON Newuser
REBUILD


3.删除索引
对于确认不再使用的索引,可以进行删除,删除索引语法如下:

DROP INDEX
<table_or_view_name>.<index_name> [ ,...n ]


【语法说明】
● table_or_view_name:指定索引列所在的表或索引视图。
● index_name:指定要删除的索引名称。
说明:DROP INDEX命令不能删除由CREATE TABLE或者ALTER TABLE命令创建的主键或者唯一性约束索引,也不能删除系统表中的索引。
4.索引的重命名
索引允许被重新命名,但新的索引名称在表或视图中必须唯一(指同一个对象中)。如果新的索引名称与现有索引同名,那么创建失败,重命名索引不会导致重新生成索引。相关语法结构如下:

sp_rename[@objname=]'object_name',
[@newname=]'new_name'
[ , [ @objtype = ] 'object_type' ]


【语法说明】
● sp_rename:关键词,表示重命名。
● [@objname=]'object_name':这里指明要重命名的索引的名称,格式为table.index。
● [@newname = ] 'new_name':新名称。
● [@objtype = ] 'object_type':要重命名的对象的类型,其默认值为NULL,如果是索引则可以用“INDEX”。
--重命名指定索引。
要求重命名索引IND_USERNAME,新名称为IND__NEWUSERNAME,相关脚本如下:

  USE Test
  GO
  --对索引IND_USERNAME进行重命名操作
  sp_rename 'Newuser.IND_USERNAME','IND_NEWUSERNAME','INDEX'
  GO
  --查看新的索引
  sp_helpindex 'Newuser'
  GO



从图中可以发现,尽管索引名称已经被更改,但其他信息没有变动。

猜你喜欢

转载自blog.csdn.net/qq_37503890/article/details/88558468