SQL Server 总览
SQL Server 不能只学成“会写 T-SQL”。商业项目里真正重要的是:数据按页怎么存、聚集索引为什么叶子层就是数据、非聚集索引为什么会 Key Lookup、事务日志为什么不能乱删、Read Committed 为什么会阻塞、RCSI 为什么吃 TempDB、参数嗅探为什么让 SQL 忽快忽慢。
学习 SQL Server 要抓住这条主线:
T-SQL 建模 -> 页和区 -> 聚集/非聚集索引 -> 优化器和执行计划 -> Buffer Pool -> 事务日志 -> 锁与行版本 -> TempDB -> 参数嗅探和生产排查。
你应该按什么顺序学
mermaid
flowchart TD
A["1. T-SQL 和建表"] --> B["2. 数据文件、日志文件、页"]
B --> C["3. 聚集索引和非聚集索引"]
C --> D["4. 执行计划、Seek、Scan、Lookup"]
D --> E["5. 事务日志、提交、恢复"]
E --> F["6. 锁、阻塞、死锁"]
F --> G["7. RCSI、TempDB、参数嗅探"]
G --> H["8. 备份、高可用、面试"]不要一开始就背 Always On 或 Query Store。先把一条查询为什么 Seek/Scan、一条更新为什么写日志和加锁理解透。
专栏学习地图
| 页面 | 学什么 | 学完要会什么 |
|---|---|---|
| 基础 T-SQL | identity、top、offset fetch、output inserted | 能写 SQL Server 常见业务 SQL |
| 从零到生产级掌握 | SQL Server 完整主线 | 能把页、索引、日志、锁、TempDB 和排查串起来 |
| 商业场景训练营 | Key Lookup、阻塞、RCSI、日志、参数嗅探 | 能把原理跑成项目能力 |
| 架构与存储 | MDF/NDF/LDF、Page、Extent、Buffer Pool | 能解释数据和日志怎么存 |
| 核心全过程原理 | 查询处理器、存储引擎、Buffer Pool、日志、锁 | 能讲 SELECT/UPDATE 全过程 |
| 索引与优化器 | 聚集、非聚集、执行计划、统计信息 | 能判断 Seek/Scan/Lookup 是否合理 |
| 索引、锁与行版本原理 | Key Lookup、RID Lookup、锁升级、RCSI | 能解释高频面试和生产问题 |
| 事务与锁 | 隔离级别、阻塞、死锁、锁等待 | 能排查接口卡住 |
| 备份与高可用 | 恢复模式、备份、日志备份、Always On | 能理解恢复和容灾边界 |
| 性能排查 | 等待、TempDB、参数嗅探、Query Store | 能按证据排查慢 SQL |
| SQL Server 面试 | 标准回答和追问 | 能短答面试题,并跳回原理页 |
从零理解 SQL Server 存储
mermaid
flowchart TD
A["Database"] --> B["Data File<br/>MDF / NDF"]
A --> C["Log File<br/>LDF"]
B --> D["Extent 区"]
D --> E["Page 页<br/>8KB"]
E --> F["Row 行"]
C --> G["Transaction Log Records"]为什么这张图重要:
| 概念 | 生产意义 |
|---|---|
| Page | 逻辑读统计的是页,不是行 |
| Buffer Pool | 热页命中内存,冷页要读磁盘 |
| LDF | 事务恢复核心,不是普通日志 |
| TempDB | 排序、Hash、版本存储、临时表都会用 |
| 聚集索引 | 决定数据行的组织方式 |
最小商业 Demo:医疗资产表
sql
create table dbo.Asset (
Id bigint identity(1,1) not null,
AssetNo varchar(64) not null,
HospitalId bigint not null,
DepartmentId bigint null,
AssetName nvarchar(128) not null,
Status varchar(20) not null,
CreatedAt datetime2 not null default sysdatetime(),
UpdatedAt datetime2 not null default sysdatetime(),
constraint PK_Asset primary key clustered (Id),
constraint UX_Asset_AssetNo unique (AssetNo),
constraint CK_Asset_Status
check (Status in ('IDLE', 'USED', 'REPAIR', 'SCRAPPED'))
);
create index IX_Asset_Hospital_Status_CreatedAt
on dbo.Asset(HospitalId, Status, CreatedAt desc)
include (AssetNo, AssetName);查询:
sql
set statistics io on;
set statistics time on;
select top (20) Id, AssetNo, AssetName, Status
from dbo.Asset
where HospitalId = 1001
and Status = 'USED'
order by CreatedAt desc;状态流转:
sql
begin tran;
update dbo.Asset
set Status = 'USED',
UpdatedAt = sysdatetime()
where AssetNo = 'A001'
and Status = 'IDLE';
commit tran;这个 Demo 背后的原理:
- 聚集主键叶子层就是数据行。
- 非聚集索引用
include减少 Key Lookup。 set statistics io on能看到逻辑读。update会获取锁、写事务日志、修改缓存页并维护索引。commit依赖日志持久化,脏页后续写回数据文件。
SQL Server 最容易被问的原理
| 问题 | 你应该跳到哪里 |
|---|---|
| 聚集索引和非聚集索引区别 | 索引与优化器 |
| Key Lookup 为什么慢 | 索引、锁与行版本原理 |
| 堆表和 RID Lookup 是什么 | 索引、锁与行版本原理 |
| 事务日志为什么不能删 | 从零到生产级掌握 |
| Read Committed 为什么阻塞 | 事务与锁 |
| RCSI 解决什么,代价是什么 | 索引、锁与行版本原理 |
| TempDB 为什么重要 | 性能排查 |
| 参数嗅探为什么忽快忽慢 | 性能排查 |
商业项目中 SQL Server 怎么用
适合:
| 场景 | 为什么适合 |
|---|---|
| .NET 企业系统 | 微软生态集成好 |
| 管理后台和审批系统 | T-SQL、权限、工具链成熟 |
| 报表和 BI | 与 Power BI、SSRS、SSIS 生态结合好 |
| 传统企业核心系统 | 运维、备份、高可用方案成熟 |
不建议:
- 把 LDF 当普通日志文件直接删。
- 只看 Index Seek,不看逻辑读和 Key Lookup 次数。
- 打开 RCSI 后不监控 TempDB。
- 大事务一次更新几十万行。
- 忽略参数嗅探,认为同一条 SQL 一定同样快。
学完 SQL Server 专栏的验收标准
你要能讲清:
- MDF、NDF、LDF 分别是什么。
- Page、Extent、Buffer Pool 为什么影响性能。
- 聚集索引叶子层为什么是数据行。
- 非聚集索引为什么会 Key Lookup。
- Heap、RID Lookup、Key Lookup 有什么区别。
- 事务日志如何支持提交、回滚、崩溃恢复。
- Read Committed 下读写为什么可能阻塞。
- RCSI 如何用行版本减少阻塞,为什么会增加 TempDB 压力。
- 参数嗅探为什么导致同 SQL 不同参数忽快忽慢。
- 慢 SQL、阻塞、死锁、TempDB、日志暴涨分别怎么排查。
面试标准回答
text
SQL Server 是微软生态常用的企业级关系型数据库。学习重点不是只会 T-SQL,而是理解数据文件 MDF/NDF、日志文件 LDF、8KB Page、Extent、Buffer Pool、聚集索引、非聚集索引、执行计划、事务日志、锁、行版本、TempDB 和参数嗅探。聚集索引叶子层就是数据行,非聚集索引叶子层保存索引键和行定位器,查询缺列时可能 Key Lookup。事务日志用于提交、回滚和崩溃恢复,不能当普通日志删除。生产排查要看实际执行计划、逻辑读、估算和实际行数、等待类型、阻塞链、TempDB、日志和 Query Store。