今天,我试图在我们公司的服务器上执行一个长时间运行(但经过高度优化)的查询。我在家用电脑(5400rpm 硬盘)上对相同的数据运行了相同的查询,大约花了 40 分钟。服务器速度慢了大约 10 倍,可能还在运行!服务器每秒插入约 30 次,我的家用电脑每秒插入 300 次。
由于 CPU 负载非常低(3%),内存充足,查询在本地执行,因此不使用网络,我怀疑磁盘 I/O 是瓶颈。而在我的家用电脑上(CPU 性能更好),两个核心几乎满载。
相关磁盘配置如下:
Windows 2003
希捷 ST3500631NS(7200 rpm,500 GB)
基于 LSI MegaRAID 的 RAID 5
4 个磁盘,1 个热备用
直写
- 无需预读
- 直接缓存模式
- 硬盘缓存模式:关闭
当然,RAID5 可能不是最快的,但是磁盘的速度像在家里一样快,从而弥补了这一缺陷。
还有一些有趣的数据:
- 平均队列长度:30
- 平均队列长度(读取):2
平均队列长度(写入):26
读取字节数/秒:1.3MB/秒
字节/秒写入:1.2MB/秒
秒/读:0.007
安全/写入:0.500
每秒写入次数:36
我该如何解决这个写入瓶颈?是因为有很多小写入吗?是不是驱动程序出现故障,或者是否有可能累积一些事务以进行更大的写入?
每次写入所花的秒数非常大!
谢谢!
答案1
我怀疑 RAID5 是罪魁祸首。每次写入阵列的块都可能导致读取,然后写入两次 - 最多(如果额外的块已经读入缓存)将是两次写入。除此之外,如果您的事务日志和数据文件位于同一阵列上,则数据库执行的每次写入都将导致两次写入(一次写入日志,一次写入数据文件) - 虽然您的家庭系统也会如此,因此它本身不会给您的比较带来太大的差异,但它会加剧任何原本存在的性能差异。
您的主驱动器可能已打开缓存,这将通过允许它稍微重新排序写入来减少磁头移动,从而提高性能。打开预读可能通过减少写入操作带来的磁头争用来帮助您,但这取决于您的查询所施加的确切 I/O 模式。
出于写入性能方面的考虑,通常建议数据库使用 RAID10,而不是 5。
当您说“相同的数据”时 - 一个系统是否运行另一个系统的备份和恢复数据库?如果两个数据库的历史记录存在差异,则可能是较慢的数据库需要更新其索引统计信息(意外的查询速度问题可能是由于基本统计信息导致查询规划器选择了比原本不太理想的路径)。
另外,两种环境中的 CPU/核心数量是否相同?前段时间,我发现 SQL Server 2000 在使用两个 CPU 时运行磁盘瓶颈查询所花的时间比仅使用一个 CPU 时要长,我推测是因为它试图将负载分散到两个 CPU 上,但这导致 I/O 争用增加,因为两个线程一起从磁盘上的不同位置读取数据(我最近没有看到这种情况,所以可能是该版本+SP 中的一个错误,早已修复,但可能值得研究 - 如果您提供了在低核环境中有帮助的显式索引提示,请尝试将其删除,以防查询规划器可以做出更适合额外核心的选择,或者尝试自己手动重新优化提示)。
答案2
直写缓存可能会影响性能。每次写入缓存时都必须立即写入磁盘。回写缓存可以等待最佳时间将数据写入磁盘。根据硬件的不同,这可能需要电池备份(在阵列控制器上),并且某些控制器会在电池缺失或需要更换时禁用写入缓存。您可能需要验证阵列缓存是否确实已启用。有些控制器不会让这一点很明显。
答案3
我们的 BI 数据集市出现了严重的 IO 问题。我发现有人重新安装了配置为 RAID 5 的硬盘之一,并根据 HP 支持重建奇偶校验;我仍然不知道是什么启动了重建。
这造成了许多麻烦,但一旦重建完成,我的性能就恢复了。这可能不是最有见地的答案,但这是您应该考虑的因素之一。