技术开发 频道

针对数据仓库和报表应用程序的10大SQL Server 2005性能问题



    【IT168 技术文档】关系数据仓库或报表工作负载的特征是事务的数量少,然而规模非常大。很容易识别这些应用程序 -- 它们通常以读取工作负载(如决策支持、分析和报告)为主,并定期执行数据补充或批量加载。在分析数据库设计、资源利用率和系统性能的重要性时,一定要记住这些特征。数据仓库或报表应用程序应避免的最大的性能瓶颈或陷阱如下所述。

在以下情况下会出现数据库设计问题……

    1.  执行过多的排序操作。如果您不断重复执行相同的排序操作,可以通过建立适当的索引来避免这些问题。
 
    2.   对堆表执行过多的 RID 查找。RID 查找意味着要检索未包含在所用的索引中的列,这需要额外的 IO。通过包含非聚簇索引可以避免这一问题。
 
    3.  针对聚簇键的键查找看起来像联接,然而它们仅在 XML 显示计划中仍被标记为“查找”。通过包含非聚簇索引可以避免这些问题。
 
   4.  在联接列上若缺失可能有益的索引会导致哈希联接。对联接列建立索引可以避免哈希。
 

CPU 陷阱……

    1.  如果信号等待时间超过总等待时间的 25%,就会出现 CPU 瓶颈。请参阅 sys.dm_os_wait_stats 以了解信号等待时间和总等待时间。信号等待时间测量的是可运行的队列等待 CPU 的时间。高信号等待时间表明存在 CPU 瓶颈。
 
    2.  避免不适当的计划重复使用。如果查询是完全相同的,那么计划重复使用是一件好事。但是,允许计划重复使用的查询参数化只有在结果集(以及中间工作表)与原始计划的大小相似时才适用。如果由于参数值的不同使结果集的大小明显不同(这在数据仓库方案中是很常见的),则计划重复使用可能是有害的。不良的计划还可能导致查询运行时间更长和 IO 或内存压力。因此,在此类情况下计划生成的成本优于计划重复使用的成本。与 OLTP 不同,数据仓库查询在结果集或非常好的查询计划方面并不总是相同的。  

在以下情况下会出现内存瓶颈……

    1.  页预期寿命突然大幅下降。DW 应用程序(如,大事务)可能会经历页预期寿命的大幅下降。这是由于大规模读取的缓存刷新造成的。请参阅 Perfmon 对象 SQL Server Buffer Manager。
 
   2.   悬而未决的内存授予。请参阅 Perfmon 对象 SQL Server Memory Manager 中的计数器内存授予挂起。大量内存授予在数据仓库应用程序中可能是很常见的。更大的内存会非常有益,否则用户在内存授予发生之前将无法执行。
 
  3.    突然下降或持续下滑的 SQL 缓存命中率。缓存命中率下降或很低可能表明内存压力或缺失索引。

在以下情况下会出现 IO 瓶颈……

   1.  衡量写入性能的非常好的标准是每次读取的磁盘秒数和每次写入的磁盘秒数。当 IO 系统未处于重大负载下时,将没有磁盘等候队列,因此每次读取或写入的磁盘秒数应达到非常好的值。通常,在没有 IO 压力的情况下完成一次读取需要 4-8 毫秒的时间。影响 IO 吞吐量的因素有磁盘轴的数量,以及驱动器吞吐量,如每秒的顺序或随机 IO(按照供应商的规定)。随着 IO 请求的增加,您可能会注意到出现了磁盘等候队列。队列的影响反映在每次读取或写入的磁盘秒数变高。对于许多应用程序来说,每次读取的磁盘秒数值周期性地升高可能是可接受的。对于高性能 OLTP 应用程序来说,完善的 SAN 子系统在处理 IO 活动尖峰中提供了更高的 IO 可放缩性和可恢复性。持续较高的每次读取的磁盘秒数值(大于 15 毫秒)表明存在磁盘瓶颈。
 
    2.   每次写入的平均磁盘秒数高。请参阅 Perfmon 逻辑或物理磁盘。在进行插入、更新或删除时可以记录数据仓库负载,在使用大容量复制时可以不做记录。记录操作需要事务日志写入。对于高性能 SAN 环境来说,事务日志写入速度最快可达到 1 毫秒(或更短)。对于许多应用程序来说,考虑到完善的 SAN 子系统的高成本,每次写入的平均磁盘秒数中出现周期性尖峰是可接受的。但是,每次写入的平均磁盘秒数值居高不下肯定表明存在磁盘瓶颈。
 
   3.  大 IO(如,表和范围扫描)可能是由于缺失索引造成的。
 

在以下情况下会出现阻塞瓶颈……

    1.  索引争用。在 sys.dm_db_index_operational_stats 中查找高锁定和闩锁等待时间。将锁定和闩锁请求进行比较。
 
    2.   高平均行锁定或闩锁等待时间。平均行锁定或闩锁等待时间是通过以下计算得出的:锁定和闩锁等待时间(以毫秒 (ms) 为单位)除以锁定和闩锁等待数。从 sys.dm_db_index_operational_stats 中计算出的平均锁定等待毫秒数表示每个阻塞的平均时间。
 
    3.   阻塞进程报告显示长时间阻塞。请参阅错误和警告事件下的 sp_configure“阻塞的进程阈值”和 Profiler“阻塞的进程报告”。
 
    4.   大量死锁。请参阅锁定事件下的 Profiler“图形化死锁”以了解死锁中涉及的内容。
 

在以下情况下会出现网络瓶颈……

    1.  高网络延迟,再加上一个会造成对数据库的多次回转访问的应用程序。
 
    2.  网络带宽已用完。请参阅性能监视器的网络接口对象中的计数器“数据包/秒”和当前的带宽计数器。对于 TCP/IP 帧,实际带宽的计算方法如下:数据包/秒 * 1500 * 8 /1000000 Mbps。
 

等待时间统计陷阱……

    1.  因为数据仓库和报表工作负载基本上都是读取,这些读取与其他读取兼容,不兼容的独占锁定等待一般仅在批量加载或定期数据补充过程中才起作用。如果顶部等待时间统计为 LCK_x. 或 PAGELATCH_EX,请参阅“使用‘等待和队列’进行 SQL Server 2005 性能调谐”以了解对 sys.dm_os_wait_stats 的说明。
 
    2.   如果 sys.dm_os_wait_stats 中的顶部等待时间统计与 IO(如 ASYNCH_IO_COMPLETION、IO_COMPLETION、LOGMGR、WRITELOG 或 PAGEIOLATCH_x)相关,就会出现 IO 瓶颈。
 

索引陷阱。

    1.  大型数据仓库可受益于更多的索引。索引可用于包含查询和避免排序。对于数据仓库应用程序来说,索引的成本开销仅在加载数据时才得到回报。
 
    2.  检查 sys.dm_db_missing_index_group_stats、sys.dm_db_missing_index_groups 和 sys.dm_db_missing_index_details 中缺失的索引
 

密切关注碎片情况。

    1.  过多的碎片会给大 IO 操作带来问题。动态管理表值函数 sys.dm_db_index_physical_stats 在 avg_fragmentation_in_percent 栏中返回碎片百分比。碎片量不应超过 25%。减少索引碎片有益于数据仓库和报表方案中常见的大范围扫描
 

考虑为实现快速负载进行表分区

    1.  对于数据仓库中常见的大型表来说,表分区能够提供重要的性能和管理优势。例如,最快的负载类型是不作记录的大容量复制。对不作记录的大容量复制的要求是必须丢弃索引。这在大到有十亿行的表中是不可行的,除非您使用表分区。允许创建一个与此大型表相同的中间表(除去索引)。快速、不作记录的大容量复制用于加载数据。随后,按照约定将索引添加到中间表中。然后,仅涉及元数据的 SWITCH IN 操作对填充的中间表和分区表中的空白目标分区切换指针位置,导致分区和空白中间表完全填充。除了快速大容量复制之外,中间表还能使我们消除加载过程中大型分区表中的阻塞。有关详细信息,请参阅“将大容量数据加载到分区表中”。除了快速加载之外,分区表还允许快速删除(或存档目的,或滑动窗口删除),其中大容量记录删除替换为仅涉及元数据的分区 SWITCH OUT 操作,为整个分区(要“删除”)和空白单块表切换指针位置。SWITCH OUT 导致一个空白分区和一个完全填充的单块中间表。随后,可以丢弃此单块表或使用 SWITCH IN 将其添加到分区存档表中。分区在与特定的文件组放置结合使用时,还能提供管理改进,允许自定义的备份和还原战略。
 

    与 OLTP 相对,数据仓库或报表应用程序以少量迥然不同的大 SELECT 事务为特征。其意义对于数据库设计、资源使用情况和系统性能是非常明显的。这些差异导致对象和资源利用情况大不相同。

0
相关文章