凌峰创科服务平台

sql server 服务器 优化

核心思想:优化不是一蹴而就的,而是一个持续监控、分析、调整的循环过程。

硬件与基础设施优化

这是性能的基石,如果硬件是瓶颈,再好的软件配置和查询优化也收效甚微。

sql server 服务器 优化-图1
(图片来源网络,侵删)
  1. CPU (中央处理器)

    • 核心数 vs. 频率:对于 SQL Server,更多的核心数通常比更高的频率更重要,因为 SQL Server 可以充分利用并行处理能力。
    • 避免 CPU 竞争:确保服务器没有运行与 SQL Server 无关的高 CPU 占用率的应用程序。
  2. 内存

    • 黄金法则尽可能多地分配内存给 SQL Server,SQL Server 是一个内存消耗大户,它会将最常用数据和执行计划缓存到内存中,以减少磁盘 I/O。
    • 配置:在 SQL Server 服务属性中,将“最大服务器内存”设置为一个合理的值(通常是物理内存的 80%-90%),为操作系统和其他应用程序预留足够空间。
    • 监控:监控 Page Life Expectation (PLE) 性能计数器,PLE 值越高越好,表示数据在内存中停留的时间越长,一般建议 PLE > 300 秒(对于 OLTP 系统)。
  3. 磁盘 I/O (输入/输出)

    • 分离数据文件和日志文件
      • 数据文件:存储数据和对象,应放置在高速磁盘上(如 SSD)。
      • 事务日志文件:记录所有事务。日志文件必须放在最快的、独立的物理磁盘上(最好是 SSD),并且最好有独立的磁盘控制器,日志写入是顺序写入,对 I/O 吞吐量要求极高。
    • 使用 RAID 级别
      • RAID 10 (镜像+条带化):最佳选择,提供极高的 I/O 性能和数据冗余,适用于数据文件和日志文件。
      • RAID 5 (条带化+奇偶校验):成本较低,但写性能较差,适用于只读或读多写少的归档数据。
      • RAID 0 (条带化):性能最高,但无冗余,仅用于临时数据,绝不能用于生产环境。
    • 考虑 SSD:对于 I/O 密集型应用(如 OLTP),将数据文件和日志文件迁移到 SSD 是最显著的性能提升之一。
  4. 网络

    sql server 服务器 优化-图2
    (图片来源网络,侵删)

    确保连接数据库服务器的网络带宽充足,延迟低,对于分布式应用,可以考虑在应用服务器和数据库服务器之间使用更快的网络连接。


SQL Server 配置优化

安装好硬件后,需要正确配置 SQL Server 自身以充分利用硬件资源。

  1. 服务器内存配置

    • 如前所述,设置 max server memory,默认值是动态的,但在生产环境中建议手动设置。
  2. 处理器配置

    sql server 服务器 优化-图3
    (图片来源网络,侵删)
    • max degree of parallelism (MAXDOP):控制一个并行查询可以使用的最大 CPU 核心数。
      • 一般建议:对于有多个核心的服务器,设置为逻辑核心数的一半,但不超过 8,一个 16 核的服务器,可以设置为 8。
      • OLTP 系统:建议设置为 1 或 2,以减少资源争用。
      • 数据仓库/报表系统:可以设置得更高(如 8 或 16)。
    • cost threshold for parallelism:决定一个查询的“成本”达到多少时才启用并行执行,默认值是 5,可以根据实际情况调高(如 20-50),以避免短小查询触发并行带来的额外开销。
  3. 高级配置

    • instant file initialization (IFI):开启此选项可以大幅加快数据文件和日志文件的初始化速度(如 RESTORE, DBCC SHRINKFILE),开启方法:在 SQL Server 策略中配置“使用 Windows 安全设置中的 Perform volume maintenance tasks 权限”,并将服务账户添加到 Administrators 组。
    • Auto growth 设置
      • 绝对不要使用百分比增长。
      • 始终使用固定 MB 增长(每次增长 1024 MB)。
      • autogrowthinitial size 设置在同一个物理磁盘上,以避免跨盘写入的性能问题。

数据库设计与对象优化

这是应用层面的优化,从根源上决定了查询效率。

  1. 规范化与反规范化

    • 规范化:减少数据冗余,提高数据一致性,但可能导致多表连接查询,增加 I/O 和 CPU 开销。
    • 反规范化:通过增加冗余数据或合并表来减少连接查询,适用于读多写少的场景,可以提高查询性能,但会增加写入的复杂性和维护成本。
    • 策略:在 OLTP 系统中,通常保持高度规范化;在报表和分析系统中,可以进行适度的反规范化。
  2. 索引策略

    • 索引是“双刃剑”:能极大加速查询,但会降低 INSERT/UPDATE/DELETE 速度,并占用存储空间。
    • 创建原则
      • WHEREJOINORDER BY 子句中频繁使用的列创建索引。
      • 覆盖索引:如果一个索引包含了查询所需的所有列(SELECT 列 + WHERE 列),数据库引擎可以直接从索引中获取数据,而无需访问数据行,性能提升巨大。
    • 避免过度索引:定期审查和删除不必要的索引。
    • 索引碎片:频繁的增删改会导致索引碎片化,降低 I/O 性能,定期使用 ALTER INDEX ... REORGANIZE(轻度整理)或 ALTER INDEX ... REBUILD(完全重建)来维护索引。
  3. 数据类型选择

    • 使用最合适的数据类型,用 INT 代替 BIGINT(如果数值范围足够),用 VARCHAR(N) 代替 NVARCHAR(N)(如果不需要存储多语言字符),可以节省存储空间并提高 I/O 和内存效率。
  4. 文件组与分区

    • 文件组:将表和索引分布到不同的文件组上,可以分散 I/O 负载。
    • 表分区:对于非常大的表(如数亿行),可以按时间、ID 等范围进行分区,这样可以实现分区切换(快速归档历史数据)、只扫描相关分区等操作,极大提高管理和查询效率。

查询与代码优化

这是最直接、最频繁的优化点。

  1. 使用执行计划

    • 最重要的工具!学会阅读和解读执行计划是优化查询的关键。
    • 关注点
      • 预估 vs. 实际行数:如果差异巨大,统计信息可能过时或查询逻辑有问题。
      • 高成本的运算符:如 Key Lookup(书签查找)、SortHash MatchNested LoopsKey Lookup 通常意味着缺少有效的索引。
      • 警告图标:黄色感叹号表示查询有潜在问题。
  2. 避免常见的 SQL 反模式

    • *`SELECT `**:只查询需要的列,减少 I/O 和网络传输。
    • WHERE 子句中对列进行函数操作:如 WHERE YEAR(OrderDate) = 2025,这会导致索引失效,应改为 WHERE OrderDate >= '2025-01-01' AND OrderDate < '2025-01-01'
    • 隐式类型转换:如 WHERE ColumnName = 123ColumnNamevarchar 类型,会导致全表扫描,确保比较两边的类型一致。
    • 不使用 JOIN 而使用子查询或 IN:有时子查询性能更好,需要通过执行计划验证。
    • OR 条件WHERE A = 1 OR B = 2 可能导致索引失效,可以尝试使用 UNION ALL 代替。
  3. 使用参数化查询

    • 使用参数化查询可以:
      • 重用执行计划:避免 SQL Server 为每次传入的微小变化的字符串重新编译查询。
      • 防止 SQL 注入
    • 在应用程序(如 ADO.NET, Entity Framework)中,默认会使用参数化查询,要避免使用字符串拼接的方式构建 SQL 语句。
  4. 事务管理

    • 保持事务尽可能短:在事务中只执行必要的操作,然后立即提交或回滚。
分享:
扫描分享到社交APP
上一篇
下一篇