SQL Server 执行计划解读与索引优化实战

为什么要懂执行计划

SQL Server 慢查询优化,本质上就是”读懂执行计划 + 让优化器选对索引”。很多开发者只会加索引,但加完还是慢,因为没看执行计划到底走了没走。本文用实操带你把执行计划读明白。

一、怎么看执行计划

在 SSMS 里两种常用方式:

  • 图形化:点”显示估计的执行计划”或”包括实际的执行计划”,执行后看拓扑图。
  • 文本化:命令行更方便分析大数据量。
SET STATISTICS IO ON;
SET STATISTICS TIME ON;
SELECT * FROM Orders WHERE CustomerId = 10086;

关注输出里的 逻辑读取 次数,这是衡量是否走索引最直接的指标——数字越小越好。

二、关键操作符识别

操作符 含义 是否该警惕
Table Scan 全表扫描 大表出现基本都要优化
Index Seek 索引查找 理想状态
Key Lookup / RID Lookup 书签查找(回表) 频繁出现说明缺覆盖索引
Sort 排序 大结果集排序很贵

三、索引优化实战

假设查询频繁按 CustomerId 过滤并取 OrderDate, Total

-- 基础非聚集索引
CREATE NONCLUSTERED INDEX IX_Orders_CustomerId
ON Orders(CustomerId);

-- 覆盖索引:把常用列 INCLUDE 进去,避免 Key Lookup 回表
CREATE NONCLUSTERED INDEX IX_Orders_CustomerId_Cover
ON Orders(CustomerId)
INCLUDE (OrderDate, Total);

加上 INCLUDE 后,执行计划里的 Key Lookup 会消失,逻辑读取从几千降到个位数。

四、最常见的几个坑

1. 列上套函数,索引失效

-- 不会走索引
SELECT * FROM Orders WHERE YEAR(OrderDate) = 2026;
-- 改写后走索引
SELECT * FROM Orders WHERE OrderDate >= '2026-01-01' AND OrderDate < '2027-01-01';

2. 隐式类型转换

字段是 varchar 但传入 nvarchar 参数,SQL Server 会对列做转换,导致索引失效。保持参数类型与列一致。

3. 前导通配符

-- 前导 % 必然全扫描
SELECT * FROM Products WHERE Name LIKE '%手机%';
-- 后导 % 才可能走索引
SELECT * FROM Products WHERE Name LIKE 'iPhone%';

五、统计信息别忘了

优化器靠统计信息估算行数。如果表长期大量增删但统计没更新,优化器可能选错计划。定期:

UPDATE STATISTICS Orders WITH FULLSCAN;

小结

执行计划不是玄学:先看有没有 Table Scan、有没有 Key Lookup、逻辑读取大不大,然后针对性建覆盖索引、改写法、更新统计。三板斧下来,大部分 SQL Server 慢查询都能解决。

上一篇 Spring Boot 统一异常处理与统一返回封装
下一篇 Kubernetes Pod 调度与故障排查实战