CentOS上 SQL Server 变慢的排查与优化清单
一 快速定位瓶颈
- 资源与系统层
- 查看内存与压力:在 SQL 中执行
- SELECT total_physical_memory_kb/1024 AS Total_MB, available_physical_memory_kb/1024 AS Available_MB FROM sys.dm_os_sys_memory;
- SELECT d.name, SUM(a.total_pages)*8/1024 AS Mem_MB FROM sys.dm_os_memory_clerks a JOIN sys.databases d ON a.database_id=d.database_id GROUP BY d.name ORDER BY Mem_MB DESC;
- 观察系统资源:使用 top/vmstat/iostat -x 1,关注 %util、await、svctm、r/s、w/s,判断是否为 CPU、内存、I/O 瓶颈。
- 数据库引擎层
- 检查等待统计:SELECT wait_type, wait_time_ms, signal_wait_time_ms, waiting_tasks_count FROM sys.dm_os_wait_stats ORDER BY wait_time_ms DESC; 优先关注 PAGEIOLATCH_XX、WRITELOG、LCK_M_XX、SOS_SCHEDULER_YIELD 等。
- 识别慢查询与计划:用 SSMS 或 Profiler 抓慢查询,查看执行计划中的 扫描/键查找/排序/哈希匹配 与 预估行数 vs 实际行数 偏差。
- 检查统计与索引健康:确保统计信息及时更新,索引碎片率在可接受范围,避免参数嗅探导致的次优计划。
二 系统与存储优化
- 硬件与文件系统
- 使用 SSD/NVMe,并尽量将 数据文件、日志文件、tempdb 分别放置在不同磁盘,减少争用。
- 选择 XFS/EXT4 等成熟文件系统,合理设置挂载选项(如 noatime),并确保对齐与条带化(RAID 场景)。
- 资源隔离与更新
- 避免与高负载服务同机部署,必要时通过 容器/虚拟机 做资源隔离。
- 保持 SQL Server 累积更新(CU)/补丁 为最新稳定版本,获取性能修复与改进。
三 数据库引擎与内存参数
- 内存
- 通过 sp_configure 设置 max server memory,专用库服务器通常设为物理内存的 50%–80%,为操作系统与其他进程预留 ≥10% 内存,避免换页与抖动。
- 并行度
- 调整 MAXDOP:一般设为 ≤ CPU 物理核心数/2;在 NUMA 环境下按节点设置更优。并发 OLTP 可适当降低,分析型大查询可适当提高。
- 临时数据库
- 将 tempdb 放在高性能磁盘;按 CPU 核心数 配置多个 tempdb 数据文件(常见做法为每个核心 1 个,最多 8 个起),初始大小一致,避免频繁自动增长。
- 统计信息与自动维护
- 启用或定期执行 自动更新统计信息,对大表/大变更后手动更新;按需 重建/重组索引、清理碎片。
四 查询与索引优化
- SQL 写法
- 避免 **SELECT ***,只取必要列;减少 函数/计算 在 WHERE/JOIN 条件中的使用;能用 JOIN 替代复杂子查询;合理使用 参数化查询 降低编译开销与计划缓存压力。
- 执行计划与索引
- 通过 SSMS/Profiler 分析执行计划,重点优化 全表扫描、键查找、排序、哈希 等昂贵操作;为高频 WHERE/JOIN/ORDER BY/GROUP BY 列建立合适索引,删除 冗余/低效 索引以降低写放大。
- 事务与锁
- 选择更合适的 隔离级别(如 READ COMMITTED SNAPSHOT 可在读多写少场景降低阻塞),并缩短事务,减少锁持有时间。
五 监控与持续优化
- 监控手段
- 使用 DMVs(如 sys.dm_os_sys_memory、sys.dm_os_wait_stats、sys.dm_db_index_physical_stats 等)做持续巡检;结合 SQL Server Profiler/Extended Events 抓慢查询与回归分析;在系统层配合 top/vmstat/iostat 与日志审计。
- 架构与扩展
- 对热点数据引入 Redis/Memcached 做缓存;读写分离或 Always On 可用性组 分担负载;对超大数据量表考虑 分区表 提升扫描与维护效率。
- 变更流程
- 任何参数/索引/查询调整先在 测试环境验证,用基准对比(如平均响应时间、P95/P99、QPS、IOPS、锁等待)评估收益,再灰度上线并保留回滚方案。