跳至主要内容

SQL Server 索引:加速数据库性能

了解 SQL Server 索引要点以优化数据库查询。学习如何高效实施与管理索引,并通过实践示例与专业技巧提升技能。
· 12分钟 阅读

使用 AI 探索

刚开始使用 SQL Server 时,我意识到并非所有的慢查询都一样。有些查询因为设计糟糕而变慢,另一些则只是效率低。但有一个发现,彻底改变了我看待数据库性能的方式:索引。想象一下,如果一本厚重的教材没有索引,您要找某一章就得不停翻页,浪费大量时间。没有适当索引的数据库,正是这种情况的翻版。

在本文中,我将解释为什么 SQL Server 索引很重要、它们如何工作,以及如何利用它们最大化数据库性能。如果您想深化在 SQL Server 上的 SQL 技能,建议学习我们的 Introduction to SQL Server 和 Intermediate SQL Server 课程,了解用于数据操作与分析的 T-SQL。

理解 SQL Server 索引

SQL Server 索引使您无需扫描整张表即可高效查询数据库中的表。下面给出 SQL Server 索引的定义及其在数据库管理中的重要性。

什么是 SQL Server 索引?

索引是一种专门的数据结构,使 SQL Server 能更高效地定位并检索行,从而节省时间和计算资源。索引通过以有利于快速搜索的方式组织数据来发挥作用。与逐行扫描整张表(称为表扫描)不同,SQL Server 可以使用索引更快地找到所需的行,而无需翻查表中的每条记录。

SQL Server 中有两种基础索引类型:

  • 聚集索引(Clustered Index): 聚集索引决定一张表中数据的物理存储顺序。当您在表上创建聚集索引后,行会按照被索引的列顺序存储在磁盘上。这对范围查询尤其有利,因为它支持对行的高效顺序访问。

  • 非聚集索引(Non-Clustered Index): 非聚集索引不会影响数据的物理顺序。它们创建一个单独的结构,包含指向实际数据行的指针。非聚集索引适用于基于未包含在聚集索引中的列进行筛选或排序的查询,以提升性能。

查看我们的 SQL Server Tutorial,了解从基础到高级的 SQL Server 数据管理用法。

为什么索引很重要?

索引对于提升查询性能和整体数据库效率至关重要。以下是使用索引的一些关键好处:

  • 更快的查询执行: 索引可减少查找与检索数据所需时间。比如,在拥有数百万行的表中搜索某一特定客户的所有订单时,在客户列上建立索引,SQL Server 几乎可以瞬时定位这些行。

  • 更高效的资源使用: 借助索引,SQL Server 完成任务所需的 CPU 与内存资源更少。这种效率在高负载下尤为关键,能转化为更好的系统整体性能。

  • 更快的排序与分组: 索引可加速涉及排序(ORDER BY)与分组(GROUP BY)的操作。通过维护有序数据,索引让 SQL Server 能快速返回结果,而无需额外的排序开销。

考虑一个索引应用的用例:在大型电商平台中,用户常按商品名称搜索。通过在商品名称列上创建非聚集索引,几乎可以让这类搜索瞬时完成,从而改善用户体验并降低服务器负载。

建议查看 DataCamp 的 SQL Server Fundamentals 技能路径,学习用于数据分析的排序、分组与表连接。

SQL Server 索引的类型

SQL Server 提供多种索引类型,各具特性与适用场景。下面讨论常见类型。

聚集索引与非聚集索引

SQL Server 的两种主要索引类型是聚集索引与非聚集索引。

聚集索引

聚集索引决定表中行的物理顺序,实质上按照索引列对表进行排序。因为数据的物理顺序只能有一种,每张表只能有一个聚集索引。对于需要返回一段范围的值或按索引列排序的查询,聚集索引是理想选择。

例如,一张按 OrderDate 排序的销售表,在 OrderDate 列上建立聚集索引就很合适。获取某日期范围内的所有订单时,查询会快很多。

非聚集索引

非聚集索引创建一个单独的结构,用于指向表中的实际行。一张表可以有多个非聚集索引,分别服务于不同的查询模式。非聚集索引包含指向实际数据的引用(行定位器),可以是行 ID 或聚集索引键。该索引适用于经常用于搜索条件或连接的列(如 EmailAddress、ProductName)。

例如,在库存表的 ProductName 列上创建非聚集索引,可在不更改表结构的前提下加速特定商品的搜索。

唯一索引与复合索引

SQL Server 还支持唯一索引与复合索引,它们各自满足特定目的。

唯一索引

唯一索引确保被索引列中的所有值都唯一。它通过防止重复值来维护数据完整性,通常用于天然唯一的列,如电子邮箱或用户名。例如,在用户表的 Email 列上创建唯一索引,可确保没有两个用户使用相同的邮箱地址。

复合索引

复合索引跨越多个列,用于优化基于这些列组合进行筛选或排序的查询。复合索引中列的顺序很重要,SQL Server 会优先处理最左侧的列。复合索引支持包含多重条件的复杂查询。例如,在客户表的 LastName 与 FirstName 上建立复合索引,可加速基于全名的客户搜索。

Index type

Key feature

Use case

Example

Clustered Index

Organizes table data by index column

Range queries, sorting

Sales table with clustered index on OrderDate

Non-Clustered Index

Separate structures pointing to rows

Filtering, joining, searching

Inventory table with non-clustered index on ProductName

Unique Index

Ensures all values are distinct

Enforcing data integrity

User table with a unique index on Email

Composite Index

Spans multiple columns

Multi-condition queries

Customer table with a composite index on LastName, FirstName

创建与管理 SQL Server 索引

我们使用 SQL Server Management Studio(SSMS)在 SQL Server 中创建索引。在进一步说明之前,先查看我们的博文,了解 SQL Server、PostgreSQL 与 MySQL 方言之间的差异。下面介绍创建与管理 SQL Server 索引的各个步骤。

如何创建 SQL Server 索引

以下是使用 SQL Server Management Studio(SSMS)与 SQL 代码创建索引的分步指南。

使用 SSMS 创建索引

  1. 打开对象资源管理器: 启动 SSMS 并连接到您的 SQL Server 实例。展开包含目标表的数据库。

Open Object Explorer and navigate the table to create the index.

打开对象资源管理器并定位到要创建索引的表。图片来源:作者。

  1. 定位表: 导航到 Tables 文件夹,找到您的表并展开。

Locate the table to create the index and expand it.

定位到要创建索引的表并展开。图片来源:作者。

  1. 打开 Indexes 文件夹: 右键单击 Indexes 文件夹并选择 New Index。

Open the Index folder and right-click to create a new index.

打开 Index 文件夹,右键创建新索引。图片来源:作者。

  1. 选择索引类型: 选择您要创建的索引类型(例如 Clustered Columnstore Index 或 Non-Clustered Index)。
  2. 定义索引属性: 指定索引名称,点击 Add 添加列并选择需要的列。配置其他选项,如唯一性与排序顺序。

Choose the index type and define the properties.

选择索引类型并定义属性。图片来源:作者。

  1. 创建索引: 点击 OK 创建索引。

Create the index by clicking ok.

点击确定创建索引。图片来源:作者。

使用 SQL 代码创建索引

您也可以直接通过 T-SQL 命令创建索引。下面是使用查询创建不同类型索引的示例:

-- Create a non-clustered index on the Product column
CREATE NONCLUSTERED INDEX IX_Sales_Product
ON Sales (Product);

-- Create a unique index on the combination of CustomerName and OrderDate
CREATE UNIQUE NONCLUSTERED INDEX IX_Sales_CustomerName_OrderDate
ON Sales (CustomerName, OrderDate);

-- Create a clustered index on the OrderDate column
CREATE CLUSTERED INDEX IX_Sales_OrderDate
ON Sales (OrderDate);

如何删除 SQL Server 索引

您可以通过简单的方法删除索引。但请务必谨慎,删除索引可能会影响查询性能。

使用 SSMS 删除 SQL Server 索引

  1. 在 Object Explorer 中,导航到表下的 Indexes 文件夹。
  2. 右键单击要删除的索引并选择 Delete。

Navigate to the index you want to delete.

导航到您要删除的索引。图片来源:作者。

  1. 在对话框中确认删除。

Confirm deletion in dialog box and click ok.

在对话框中确认删除并点击确定。图片来源:作者。

使用 T-SQL 删除索引

您可以使用以下命令从 SQL Server 的表中删除现有索引。

-- Drop a non-clustered index
DROP INDEX IX_Sales_Product ON Sales;

-- Drop a clustered index
DROP INDEX IX_Sales_OrderDate ON Sales;

如何重组 SQL Server 索引

重组索引会对索引的叶级页面进行碎片整理,在不完全重建的情况下提升性能。

使用 SSMS 重组 SQL Server 索引

  1. 右键单击索引,然后转到 Reorganize All。

Right-click indexes, then Reorganize All.

右键单击索引,选择 Reorganize All。图片来源:作者。

  1. 选择要重组的索引并确认。

Select the indexes to reorganize, then confirm.

选择要重组的索引并确认。图片来源:作者。

使用 T-SQL 重组索引

您也可以使用以下查询在 SQL Server 中重组索引。

-- Reorganize a single index
ALTER INDEX IX_Sales_Product
ON Sales
REORGANIZE;

-- Reorganize all indexes on the table
ALTER INDEX ALL
ON Sales
REORGANIZE;

如何重建 SQL Server 索引

重建索引会从零开始重新创建索引,消除碎片并优化存储。

使用 SSMS 重建索引

  1. 右键单击索引,然后转到 Rebuild All。

Right-click the index, then go to Rebuild All.

右键单击索引,选择 Rebuild All。图片来源:作者

  1. 选择要重建的索引并确认。

Select the indexes to rebuild and confirm.

选择要重建的索引并确认。图片来源:作者

使用 T-SQL 重建索引

以下查询将重建表上的索引。

-- Rebuild a single index
ALTER INDEX IX_Sales_Product
ON Sales
REBUILD;

-- Rebuild all indexes on the table
ALTER INDEX ALL
ON Sales
REBUILD;

索引管理最佳实践

维护与优化 SQL Server 索引对于确保数据库达到最佳性能至关重要。以下是行之有效的索引管理建议。

  • 定期进行索引维护: 定期重组或重建索引以降低碎片化程度,避免性能随时间下降。使用维护脚本或 SQL Server Maintenance Plans 等工具自动化这些任务。

  • 分析索引使用情况: 使用动态管理视图(DMV),如 sys.dm_db_index_usage_stats,识别未使用或利用率低的索引。删除无明显性能收益的索引,以避免不必要的开销。

  • 避免过度建索引: 过多的索引会拖慢写入操作(INSERT、UPDATE、DELETE),因为相关索引都需要更新。聚焦于经常用于 SELECT 查询、连接或筛选条件的列。

  • 监控碎片程度: 使用 sys.dm_db_index_physical_stats 识别高度碎片化的索引。碎片低于 30% 可重组,超过 30% 则应重建。

  • 利用筛选索引: 对仅作用于数据子集的查询(如活跃用户或特定日期范围)使用筛选索引以优化性能。

您还应关注以下做法,以避免管理索引时的常见陷阱:

  • 过度建索引: 不要为每个查询都创建索引;这会影响写入操作并占用存储。

  • 忽视维护: 不重建或不重组索引会导致碎片增加。

  • 忽略写入时的索引影响: 虽然索引加速读取,但可能显著拖慢写入。

  • 未测试复合索引: 复合索引中列顺序不当会让索引失效。

查看 DataCamp 的 SQL Server for Database Administrators 技能路径,进一步学习事务与错误处理,以提升查询性能。

性能考量

索引有助于优化数据库性能,但也伴随取舍。理解其影响并有效管理,对于维持高性能数据库系统至关重要。

索引对查询性能的影响

索引通过减少数据检索时间,显著影响查询执行计划与性能。当存在有效索引时,SQL Server 能快速定位行,减少代价高昂的全表扫描。在执行计划中,常能看到 Index Seek 替代表扫描(Table Scan)。

衡量索引性能的工具包括:

  • sys.dm_db_index_usage_stats 跟踪查询对索引的使用情况。

  • sys.dm_db_index_operational_stats 提供页面读写等操作指标。

  • Query store analyzes query performance and identifies inefficiencies caused by missing or unused indexes.

例如,下面的查询可检索用户表中索引的使用统计信息,包括 seek、scan、lookup 与 update 的明细,帮助评估索引的有效性与性能。

-- Retrieve index usage statistics for user tables
SELECT 
    OBJECT_NAME(IXS.OBJECT_ID) AS TableName, 
    I.name AS IndexName,
    IXS.user_seeks AS Seeks,
    IXS.user_scans AS Scans,
    IXS.user_lookups AS Lookups,
    IXS.user_updates AS Updates
-- DMV providing index usage stats
FROM 
    sys.dm_db_index_usage_stats IXS         
JOIN 
    sys.indexes I ON I.OBJECT_ID = IXS.OBJECT_ID 
                 AND I.index_id = IXS.index_id
WHERE 
    OBJECTPROPERTY(IXS.OBJECT_ID, 'IsUserTable') = 1;

平衡索引使用与存储

虽然索引能提升数据库性能,但也会消耗存储空间,尤其是在大型数据集上。实施索引时需要平衡这些因素。更多的索引可能拖慢写入操作,特别是在高事务环境中。考虑以下策略以平衡索引使用:

  • 只为关键列建索引: 重点索引常出现在 WHERE、JOIN 与 ORDER BY 子句中的列。避免为很少查询的列建立索引。

  • 使用筛选索引: 针对数据子集创建索引,以节省空间并优化特定查询。

  • 利用压缩: 启用数据压缩,减少索引的存储占用。

  • 归档旧数据: 将很少访问的数据移动到归档表,并减少主表上的索引。

以上策略可在确保查询性能的同时,控制存储与维护成本。

排查索引问题

如果维护不当,索引会随着时间推移而退化,降低数据库效率。下面讨论如何识别并解决这些问题。

  • 碎片化: 随着时间推移,索引会产生碎片,导致数据检索低效。症状包括查询执行时间增加、磁盘 I/O 偏高。解决方法:使用 sys.dm_db_index_physical_stats 识别碎片情况;碎片低于 30% 时重组,超过 30% 时重建。

  • 统计信息过期: 过时的统计信息会导致非最优的查询执行计划,即便索引合适也可能出现慢查询。解决方法:对关键索引手动更新统计信息,或启用 AUTO_UPDATE_STATISTICS。

  • 未使用或冗余索引: 有些索引长期不被使用,却占用存储并拖慢写入。症状表现为索引维护成本高、查询收益低。解决方法:使用 sys.dm_db_index_usage_stats 识别未使用索引,并视情况删除。

  • 缺失索引: 缺乏合适的索引会导致表扫描,拖慢查询。在这类场景下,执行计划会显示 Table Scan 而非 Index Seek。解决方法:使用缺失索引 DMV sys.dm_db_missing_index_details 识别机会,并基于查询模式创建推荐索引。

  • 重叠索引: 多个具有相似列结构的索引会浪费资源,增加存储与维护的冗余。应将重叠索引整合为单个设计良好的索引。

试试我们的 SQL Server Developer 职业路径,进一步学习在 SQL Server 中排查索引问题,提升数据库效率。

结语

若要通过编写高效查询来提升数据库性能,掌握 SQL Server 索引至关重要。在使用索引时,您也应理解不同类型的 SQL Server 索引,以便更好地管理索引,获得最佳数据库性能。

建议学习我们的 Associate Data Analyst in SQL 职业路径,成为一名熟练的数据分析师。我们的 Reporting in SQL 课程也将帮助您熟练构建复杂报表与仪表板,以高效呈现数据。如果您正在准备需要展示 SQL Server 技能的面试,建议查看我们的博文 Top 30 SQL Server Interview Questions,助您练习并在面试中脱颖而出。

Allan Ouko

作者

Allan Ouko

数据科学技术写作者,具备数据分析、商业智能和数据科学的一线实践经验。我撰写以行业为导向的实用内容,涵盖 SQL、Python、Power BI、Databricks 和数据工程,并以真实的分析工作为基础。我的写作兼顾技术深度与业务影响,帮助专业人士将数据转化为自信的决策。

FAQs

什么是 SQL Server 索引?

SQL Server 索引是一种数据库对象,通过为数据提供快速访问路径来加速表上的数据检索操作。

为什么 SQL Server 索引很重要?

索引通过减少数据检索时间并优化资源使用,对提升查询性能至关重要。

如何在 SQL Server 中创建索引?

您可以通过 SQL Server Management Studio 创建索引,或在 SQL 中执行 CREATE INDEX 语句。

聚集索引与非聚集索引有什么区别?

聚集索引根据索引键对表的数据行进行排序并存储;非聚集索引则创建单独的结构来存储索引键与指向数据行的指针。

什么是唯一索引与复合索引?

唯一索引确保索引键中没有重复值;复合索引使用多个列构成索引键。

主题