SQL Server 2022查询性能优化核心是规避人为误操作:禁用SELECT *和DISTINCT以减少I/O与内存压力;避免WHERE中使用函数导致索引失效;按最左前缀原则设计索引并善用included_columns;谨慎启用自动调优,设阈值、关自动删索引、黑名单高频写表;优化须匹配SLA与资源预算。

SQL Server 2022 的 SELECT 查询性能优化,核心不在于“加功能”,而在于让已有机制更可靠、更自动、更少出错——尤其是避免人为误操作和过时经验带来的反效果。
避免 SELECT * 和 DISTINCT 是硬性起点
这两类写法在 SQL Server 2022 中依然会放大 I/O 和内存压力,且无法被智能查询处理(IQP)缓解。即使启用了自动索引或参数敏感计划,它们仍会强制读取全部列或触发额外的去重排序步骤。
-
SELECT *会让执行计划无法利用覆盖索引,哪怕你只用其中 2 列,也会拉回整行数据(含 LOB 字段),拖慢网络和缓存效率 -
SELECT DISTINCT在多数场景下可被业务逻辑前置过滤替代;若必须用,确保DISTINCT字段组合上有合适索引,否则会走哈希匹配或排序,P99 延迟极易飙升 - 检查现有视图或 ORM 生成语句:很多框架默认生成
SELECT *,需在查询层显式指定字段列表
WHERE 条件里别碰函数,尤其 DATEPART、CAST、CONVERT
这类写法直接让索引失效,SQL Server 2022 的 IQP 也无法“修复”这种设计级问题。优化器再聪明,也变不出函数包裹列后的统计信息分布。
- 错误示例:
WHERE YEAR(OrderDate) = 2024→ 强制全表扫描,OrderDate上的索引完全闲置 - 正确写法:
WHERE OrderDate >= '2024-01-01' AND OrderDate ,能命中索引范围查找 - 对
datetime2字段做比较时,避免隐式转换:比如把字符串'2024-03-15'直接和datetime2列比,SQL Server 可能选错类型推导路径,改用显式CONVERT(datetime2, '2024-03-15')反而更稳
用 sys.dm_db_missing_index_* 主动找索引缺口,别等慢了再救火
SQL Server 2022 的缺失索引 DMV 依然有效,但要注意它只反映“过去执行过的查询”的模式,不会预测未来。关键是要结合实际负载筛选,而非照单全建。
- 运行标准缺失索引查询后,重点关注
avg_total_user_cost * avg_user_impact * (user_seeks + user_scans)得分高的项,得分 - 检查
equality_columns和inequality_columns是否匹配你最常跑的 WHERE 条件顺序;例如查询是WHERE StatusID = 1 AND CreatedDate > '2024-01-01',那索引列序应为(StatusID, CreatedDate),反过来效果差很多 - 注意
included_columns:如果查询 SELECT 的字段都能被包含列覆盖,就能避免键查找(Key Lookup),这是 2022 中仍最有效的单点优化手段之一
打开自动调优但别全信,尤其 CREATE_INDEX 和 DROP_INDEX
SQL Server 2022 的 AUTOMATIC_TUNING 确实能自动建删索引,但它基于统计模型而非业务语义。生产环境启用前必须设好边界,否则可能在高峰期自动生成低效索引,或误删高频查询依赖的索引。
- 至少配置三项:
FORCE_LAST_GOOD_PLAN=ON(防计划回归)、CREATE_INDEX=ON(配合阈值)、DROP_INDEX=OFF(先关掉自动删,人工确认后再开) - 用
sp_automatic_tuning_set_threshold @feature='CREATE_INDEX', @threshold=50把收益门槛提到 50%,避免为 5% 提升建一堆维护成本高的索引 - 对审计表、日志表等高频写入低频查的表,务必用
sp_automatic_tuning_set_blacklist加入黑名单,否则自动索引可能拖垮写入吞吐
真正难的不是知道该建什么索引,而是判断“这个查询值不值得优化”——有些 SELECT 本就该走全表扫描,比如报表类查询每天只跑一次、返回百万行;强行加索引反而抬高写入成本。优化永远要绑定具体 SLA 和资源预算,而不是追求“执行时间从 800ms 降到 200ms”这种孤立指标。


















