目录
一、索引定义
二、索引结构
2.1. B-树索引结构:
2.2. 哈希索引结构:
三、索引作用
四、索引与约束区别
五、索引级别
六、索引分类
6.1. 聚集索引(Clustered Index):
6.2. 非聚集索引(Nonclustered Index):
6.3. 唯一索引(Unique Index):
6.4. 全文索引(Full-Text Index):
6.5. 空间索引(Spatial Index):
示例1:地理位置
示例2:几何位置
七、索引检查
7.1. 使用系统视图:
7.2. 使用SQL Server Management Studio(SSMS):
7.3. 使用sp_helpindex存储过程:
八、索引的应用场景
8.1. 聚簇索引(Clustered Index):
8.2. 非聚簇索引(Non-Clustered Index):
8.3. 全文索引(Full-Text Index):
8.4. 空间索引(Spatial Index):
8.5.唯一索引
索引是一种用于加快数据库查询速度的数据结构。它类似于书籍的目录,可以帮助快速查找特定数据行。索引由一个或多个列组成,并按照特定顺序存储这些列的值。当执行查询时,数据库可以使用索引来定位并访问所需的数据,从而避免全表扫描,提高查询性能。
因此索引常用于改进数据请求的性能。在一个完美的世界里,可以创建大量的索引以满足用户所创建的每一项查询排序的需求。当然,索引必须得到维护。插入、更新、删除数据时,索引必须重新计算。我们要权衡索引的创建,也就是说,当我们创建足够多的索引以改进查询性能时,也需要考虑到尽量不影响对数据的修改。
在SQL Server中,索引的结构通常基于B-树(B-Tree)或哈希(Hash)实现。这些结构可以有效地组织和存储索引数据,以提供快速的查询和检索操作。
无论是B-树索引还是哈希索引,它们都旨在提供快速的索引访问和数据检索,以优化数据库查询性能。具体选择哪种索引结构取决于数据的特征、查询模式以及性能需求。
索引具有以下作用和功能:
总之,索引在SQL Server中起到了加速查询、优化性能、确保数据完整性和安全性等多方面的作用和功能。合理使用和设计索引可以显著改善数据库的性能和响应时间。
索引和约束是两个不同的概念,它们有以下区别:
总体而言,索引用于优化查询性能,提高数据访问速度,而约束用于保持数据的完整性和一致性。索引是数据库内部的数据结构,而约束是逻辑上规定的规则。理解和正确使用索引和约束可以提高数据库的性能和数据质量。
将索引可以分为以下几个级别:
表级索引是应用于整个表的索引。它们可以提供对表中所有行的快速访问,并且适用于那些经常需要全表扫描的查询。
列级索引仅应用于单个列。它们可以加快特定列上的查询速度,特别是当这些列在WHERE条件或JOIN操作中经常使用时。
聚集索引决定了数据在磁盘上的物理排序顺序。在表中创建聚集索引后,表的数据行将按照索引列的值进行排序。一个表只能有一个聚集索引,因为它决定了数据在磁盘上的存储方式。
非聚集索引是基于表中一个或多个列的值创建的,但并不决定数据在磁盘上的物理排序顺序。非聚集索引包含索引列的副本和指向实际数据行的指针。一个表可以有多个非聚集索引,用于加速特定列或多列的查询操作。
覆盖索引是一种非聚集索引,它包含了查询语句所需的所有列。当查询只需要从索引中获取数据而无需查找实际数据行时,覆盖索引可以显著提高查询性能。
全文索引用于对文本列进行全文搜索。它创建了一个包含关键词的词汇表,并使用倒排索引来快速定位匹配的文档。
在SQL Server 2008中,索引可以按照不同的分类方式进行分类。以下是SQL Server 2008中常见的索引分类:
聚集索引定义了表的物理排序顺序,决定了数据在磁盘上的存储方式。每个表只能有一个聚集索引,它对应于表的主键或唯一约束。聚集索引确定了数据行在表中的物理顺序,因此对于某些查询和排序操作具有很高的性能优势。
示例:
通过以下例子来演示如何创建和使用聚集索引:
假设有一个名为"Customers1"的表,包含以下列:CustomerID(主键)、FirstName、LastName、Email。
--1.创建customers1:可以使用CREATE TABLE语句来创建表。 CREATE TABLE Customers1 ( CustomerID INT PRIMARY KEY, FirstName VARCHAR(50), LastName VARCHAR(50), Email VARCHAR(100) ); select * from Customers1 ; --2.插入数据 INSERT INTO Customers1 (CustomerID, FirstName, LastName, Email) VALUES (1, 'John', 'Doe', 'john@example.com'); INSERT INTO Customers1 (CustomerID, FirstName, LastName, Email) VALUES (2, 'Jane', 'Smith', 'jane@example.com'); --3.创建聚集索引(创建表结构时其实已经有了聚集索引,此时再次创建无法成功,需要先删除原来的聚集索引,换个说法就是对原来的聚集索引进行重命名) --使用CREATE CLUSTERED INDEX语句来创建聚集索引。将聚集索引定义为表的主键。 CREATE CLUSTERED INDEX PK_Customers ON Customers1(CustomerID); /*这将创建一个名为PK_Customers的聚集索引,基于CustomerID列。*/ --4.查询使用聚集索引 -- 查询单个客户信息 SELECT * FROM Customers1 WHERE CustomerID = 1; -- 根据姓氏排序查询所有客户 SELECT * FROM Customers1 ORDER BY LastName;
聚集索引确定了数据行在表中的物理顺序,对于按照主键或排序字段进行查询的操作具有很高的性能优势 。
没有聚集索引的表称为“堆”表。一般而言,每张表都会有一个聚集索引。在每张表上创建聚集索引的主要原因之一是消除转发指针。
可以回忆一下所用到的创建表的脚本,虽然主键是一种约束,但在物理上SQL Server将其用作索引。由于主键的默认选项是聚集(“clustered”),因此SQL Server将为主键创建一个聚集索引。类似地,唯一约束在物理上也被用作唯一索引。因为主键也是唯一的,默认状态下SQL Server在物理上将主键用作一个唯一的聚集索引。
非聚集索引创建一个单独的结构来存储索引列的值和指向存储实际数据行的位置的指针。与聚集索引不同,表可以有多个非聚集索引。非聚集索引通常用于加速查询操作,通过提供快速的索引扫描来定位到符合条件的数据行。
示例:
通过以下例子来演示如何创建和使用非聚集索引:
假设有一个名为"Products3"的表,包含以下列:ProductID(主键)、ProductName、Category、Price。
--1.创建表:使用CREATE TABLE语句来创建表 CREATE TABLE Products3 ( ProductID INT PRIMARY KEY, ProductName VARCHAR(100), Category VARCHAR(50), Price DECIMAL(10, 2) ); --2.插入数据 INSERT INTO Products3 (ProductID, ProductName, Category, Price) VALUES (1, 'iPhone', 'Electronics', 999.99); INSERT INTO Products3 (ProductID, ProductName, Category, Price) VALUES (2, 'Samsung TV', 'Electronics', 899.99); INSERT INTO Products3 (ProductID, ProductName, Category, Price) VALUES (3, 'Dell Laptop', 'Electronics', 1499.99); select * from Products3 ; --3.创建非聚集索引 --使用CREATE NONCLUSTERED INDEX语句来创建非聚集索引。将非聚集索引定义为表的某个列或多个列。 CREATE NONCLUSTERED INDEX IX_Category ON Products3(Category); /*这将创建一个名为IX_Category的非聚集索引,基于Category列。*/ --4.查询使用 -- 按照类别查询所有电子产品 SELECT * FROM Products3 WHERE Category = 'Electronics'; -- 根据价格排序查询所有产品 SELECT * FROM Products3 ORDER BY Price;
唯一索引确保索引列的值是唯一的,在表中不存在重复的值。唯一索引可以是聚集索引或非聚集索引,用于实现唯一性约束,并防止重复数据的插入。
示例:
通过以下例子来演示如何创建和使用唯一索引:
假设有一个名为"Employees2"的表,包含以下列:EmployeeID(主键)、FirstName、LastName、Email。
--1.创建表: CREATE TABLE Employees2 ( EmployeeID INT PRIMARY KEY, FirstName VARCHAR(50), LastName VARCHAR(50), Email VARCHAR(100) ); --2.插入数据 INSERT INTO Employees2 (EmployeeID, FirstName, LastName, Email) VALUES (1, 'John', 'Doe', 'john@example.com'); INSERT INTO Employees2 (EmployeeID, FirstName, LastName, Email) VALUES (2, 'Jane', 'Smith', 'jane@example.com'); --3.创建索引 CREATE UNIQUE INDEX UX_Email ON Employees2(Email); --4.插入数据时使用索引 -- 尝试插入重复的Email值,会引发错误 INSERT INTO Employees2 (EmployeeID, FirstName, LastName, Email) VALUES (3, 'Bob', 'Johnson', 'john@example.com'); --5.查询使用唯一索引 -- 根据Email查询员工信息 SELECT * FROM Employees2 WHERE Email = 'john@example.com';
提示:
在SQL Server 2008中,如果对表的某列设置了唯一约束(UNIQUE constraint),SQL Server会自动为该列创建一个唯一索引(Unique Index)。这个唯一索引用于实现唯一性约束,并确保该列的值在表中是唯一的。
唯一索引和唯一约束是紧密相关的概念,它们的目标都是确保列的值是唯一的。当我们在创建表时对某列设置了唯一约束,SQL Server会自动创建一个唯一索引来支持这个约束。这样,在插入、更新或删除数据时,系统会自动维护这个唯一索引,以保证唯一性约束的有效性。
因此,如果在SQL Server 2008中创建表时对某列设置了唯一约束,那么相应的唯一索引将会被自动创建。这个唯一索引可以提供快速的唯一值验证和快速访问具有特定值的行的能力。
全文索引用于实现全文搜索功能,对包含文本数据的列进行索引。全文索引支持文本模式匹配、关键字搜索等高级搜索操作,并提供了更快速和精确的搜索结果。
示例:
--全文索引示例 --创建包含5条以上数据的表MyTable,并为 Description 列创建全文索引 --1.创建表 CREATE TABLE MyTable ( ID INT PRIMARY KEY, Title NVARCHAR(100), Description NVARCHAR(MAX) ); --2.插入数据 INSERT INTO MyTable (ID, Title, Description) VALUES (1, 'Product A', 'This is the description for Product A.'), (2, 'Product B', 'Product B is a high-quality product.'), (3, 'Product C', 'Description of Product C.'), (4, 'Product D', 'Product D comes in different colors.'), (5, 'Product E', 'The features of Product E include...'), (6, 'Product F', 'Product F is suitable for...'); --3.创建全文索引 -- 创建一个用于存储全文索引的目录(如果已存在,则不需要再次创建) CREATE FULLTEXT CATALOG MyCatalog; -- 在表上创建全文索引 CREATE FULLTEXT INDEX ON MyTable(Description) KEY INDEX PK_MyTable_ID -- 基于主键或唯一键列创建索引 WITH STOPLIST = SYSTEM; -- 指定停用词列表 --4.启用全文索引 ALTER FULLTEXT INDEX ON MyTable START UPDATE POPULATION; --5.使用全文索引进行查询 SELECT ID, Title FROM MyTable WHERE CONTAINS(Description, 'product'); --查询返回匹配关键字 "product" 的记录,可以根据实际需求调整搜索条件; --CONTAINS 函数用于指定要搜索的列和搜索条件, --可以使用各种全文搜索运算符(例如 AND、OR、NEAR 等)来构建复杂的搜索条件。 --管理全文索引的语句: -- 禁用全文索引 ALTER FULLTEXT INDEX ON Products STOP UPDATE POPULATION; -- 重新启用全文索引 ALTER FULLTEXT INDEX ON Products START UPDATE POPULATION; -- 查看全文索引状态 SELECT FULLTEXTCATALOGPROPERTY('MyCatalog', 'PopulateStatus') AS Status; /* 报错:不存在默认全文目录,或用户没有执行此操作的权限。 可能是由于以下原因之一: 1.目录不存在:你可以尝试手动创建一个全文目录,然后再创建全文索引。使用以下语句创建全文目录: CREATE FULLTEXT CATALOG MyCatalog; 请确保将 MyCatalog 替换为你想要使用的目录名称。 2.没有足够的权限:如果你没有足够的权限创建全文目录, 可以尝试使用具有相应权限的管理员账户或联系数据库管理员以获取权限。 */
假如你使用的系统用户然后创建表,即用 `sa` 用户登录到数据库可以创建全文目录但是无法创建全文索引,可能是由于以下原因之一:
注意:
全文索引需要满足一些特定的条件才能创建成功。以下是创建全文索引的要求:
全文索引只能针对唯一且非空的单列索引。
全文索引不能创建在计算列、非持久化计算列或有筛选器的列上。
全文索引的最大大小限制为900个字节。
全文索引的基础表必须位于同一文件组中。
全文索引必须基于全文目录。
否则就会出现报错:
'PK_...' 不是可强制使用全文搜索键的有效索引。全文搜索键必须是唯一的、不可为 Null 的单列索引,并且该索引不是脱机的,不是在不确定的或不精确的非持久化计算列上定义的,没有筛选器,且最大大小为 900 个字节。请为全文键选择其他索引。
空间索引用于管理和查询空间数据,如地理位置数据和几何图形数据。它们可以加速空间相关的查询操作,例如搜索附近的地点或执行空间范围查询。
当涉及到使用空间索引时,SQL Server 2008支持两种类型的空间数据:几何(Geometry)和地理(Geography),以下是两个示例:
--空间索引示例1:地理位置 --使用空间索引来管理和查询包含地理位置或几何形状数据的列 --1.创建表来存储地理位置数据: CREATE TABLE Locations ( LocationID INT PRIMARY KEY, LocationName VARCHAR(50), Point GEOGRAPHY ); --2.插入数据 INSERT INTO Locations (LocationID, LocationName, Point) VALUES (1, 'New York', geography::Point(40.712776, -74.005974, 4326)), (2, 'London', geography::Point(51.507351, -0.127758, 4326)), (3, 'Tokyo', geography::Point(35.689487, 139.691711, 4326)); select * from Locations; --3.创建空间索引 CREATE SPATIAL INDEX idx_Spatial ON Locations(Point) USING GEOGRAPHY_GRID WITH ( GRIDS = (LEVEL_1 = MEDIUM, LEVEL_2 = HIGH, LEVEL_3 = HIGH, LEVEL_4 = MEDIUM), CELLS_PER_OBJECT = 16 ); --GRIDS参数定义了网格的级别,以及每个级别中的单元格数量 --4.查询使用空间索引的数据 -- 比如查找距离给定经纬度小于10公里的地点 SELECT LocationName FROM Locations WHERE Point.STDistance(geography::Point(40.712776, -74.005974, 4326)) <= 10000; --该查询将返回距离给定经纬度(纽约市)小于等于10公里的地点名称。
--空间索引示例2:几何位置 --1.创建表来存储几何位置数据: CREATE TABLE Buildings ( BuildingID INT PRIMARY KEY, BuildingName VARCHAR(50), Shape GEOMETRY ); --2.插入数据: INSERT INTO Buildings (BuildingID, BuildingName, Shape) VALUES (1, 'Building A', geometry::STPolyFromText('POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))', 0)), (2, 'Building B', geometry::STPolyFromText('POLYGON ((5 5, 15 5, 15 15, 5 15, 5 5))', 0)), (3, 'Building C', geometry::STPolyFromText('POLYGON ((20 20, 30 20, 30 30, 20 30, 20 20))', 0)); --在这里使用STPolyFromText函数将文本表示的多边形转换为几何数据。 select * from Buildings; --3.创建空间索引: CREATE SPATIAL INDEX idx_Spatial ON Buildings(Shape) USING GEOMETRY_GRID WITH ( BOUNDING_BOX = (-90, -180, 90, 180), -- 索引的包围盒范围 GRIDS = (LEVEL_1 = MEDIUM, LEVEL_2 = HIGH, LEVEL_3 = HIGH, LEVEL_4 = MEDIUM), CELLS_PER_OBJECT = 16 ); --BOUNDING_BOX参数定义了索引的包围盒范围,可以根据自己的数据范围进行调整。 --4.查询使用空间索引数据: --查询返回与给定查询区域(矩形)相交的建筑物名称 DECLARE @queryArea GEOMETRY; SET @queryArea = geometry::STPolyFromText('POLYGON ((2 2, 8 2, 8 8, 2 8, 2 2))', 0); SELECT BuildingName FROM Buildings WHERE Shape.STIntersects(@queryArea) = 1; -- 查找与给定查询区域相交的建筑物
在SQL Server 2008中,可以使用以下方法来查看索引信息:
SQL Server提供了多个系统视图来查询数据库对象的元数据信息,包括索引。以下是一些常用的系统视图:
查询表的索引信息语法:
SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID('TableName');
例如查看表Products中的索引信息:
SSMS是一个用于管理和操作SQL Server的集成开发环境。通过连接到数据库实例,可以使用SSMS的图形界面来查看数据库对象的属性,包括索引。在Object Explorer中展开数据库和表节点,右键点击表并选择"Indexes/Keys"选项,即可查看索引的列表。如图所示:
SQL Server提供了一个名为sp_helpindex的系统存储过程,可用于查看表的索引信息。执行存储过程,并指定要查看索引信息的表名即可。
EXEC sp_helpindex 'TableName';
例如:依旧查看表Products中的索引信息,结果如下:
无论使用哪种方法,以上都可以查看到表的索引信息,包括索引名称、类型、关联的列、是否唯一等属性。这些信息可以帮助我们了解数据库中的索引结构,并进行性能调优和索引设计。但是需要注意,当SQL Server版本较旧时,某些功能可能有所不同或缺失,建议升级到较新的版本以获得更多功能和改进。
在SQL Server中,各种索引类型常用于以下场景:
根据不同的数据和查询需求,选择适当的索引类型可以提高查询性能和数据访问效率。在设计和创建索引时,请考虑到数据的特点和所需的查询操作,并根据实际测试和性能优化的结果进行调整。
总结来说,全文索引适用于需要进行文本搜索和高级搜索的应用场景,而空间索引则适用于需要处理地理位置数据和执行空间查询的应用场景。根据具体需求,您可以选择使用其中一种或两种索引类型来优化数据检索和查询的性能。唯一索引在确保数据完整性、避免重复数据、加速查找操作和支持外键约束等方面起着关键作用。在设计数据库架构时,根据业务需求和数据模型,选择合适的列或列组合创建唯一索引是很常见的做法。