我本质上是一个开发人员 - 但时不时地,客户没有合适的 DBA 来处理这些问题,所以我会被叫来做决定......
在处理合理大小的 SQL Server 数据库(大于 Northwind 或 AdventureWorks;大约 2-4GB 的数据加上索引等)时,您的策略/最佳实践是什么 - 您是否使用多个文件/文件组?
如果有的话,有多少?为什么?
您决定何时放弃“一个文件组适用于所有内容”方法的标准是什么:
* database size?
* database complexity?
* availability / reliability requirements?
* what else?
如果您使用多个文件组,您会使用多少个?一个用于数据,一个用于索引,一个用于日志?几个(多少个)用于数据?您选择的理由是什么 - 为什么使用这个确切数量的文件组 :-)
谢谢您的任何提示、指点和想法!
干杯,马克
答案1
基本的经验法则是将文件分开到不同的卷上以避免争用,但是您获得的性能增益量会因 I/O 子系统和工作负载的不同而有很大差异。例如,单个物理主轴上的多个文件在性能方面会很糟糕,但将卷放在具有数百个来自 RAID 10 阵列的驱动器的 SAN LUN 上进行同样的安排可能就没问题了。磁盘队列长度计数器是您的好帮手,因为它是判断您是否遇到 I/O 瓶颈的最简单方法。
您正在查看数据库上的 I/O 模式 - 只读、主要读取、读写、主要写入、只写 - 并以此为基础。您还需要选择正确的 RAID 级别,并确保正确设置磁盘分区偏移量、RAID 条带大小和 NTFS 分配单元大小。有些人喜欢将非聚集索引分离到单独的文件组中,但这里的性能提升会有所不同,正如我上面所解释的那样。
除了性能之外,您还应该考虑可管理性和可恢复性。对于 100GB 的数据库,如果只有一个整体数据文件,则意味着您的恢复单位就是该文件。将其拆分为 4 个 25GB 的文件组意味着您可以使用部分数据库可用性和分段恢复,以便在文件组损坏时只需恢复单个文件组。通过将表和索引划分为多个文件组,您还可以限制数据库的哪些部分会受到维护操作的影响(例如索引碎片删除)。
Tempdb 是一个完全特殊的案例,我将向您指出我的一篇博客文章,其中解释了为什么以及如何拆分 tempdb - 其中存在很多误解。
在这里,我不会给你一个“笼统概括”的建议,而是会向你推荐一些白皮书和博客文章供你阅读:
- 白皮书:物理数据库存储设计
- 白皮书:部署前 I/O 最佳实践
- 白皮书:SQL Server 2005 中的分区表和索引
白皮书:部分数据库可用性
博客文章:关于 TF 1118 的误解(tempdb 布局)
- 博客文章:您的磁盘分区偏移、RAID 条带大小和 NTFS 分配单元是否设置正确?(附磁盘分区白皮书链接)
希望这对你有帮助!
答案2
在分析了表的当前大小和未来增长情况后,应决定将数据库拆分为不同的文件组。在我看来,除非您拥有大型数据库或包含数百万行的表,否则您应该仔细考虑利弊,因为您最终可能会产生比修复更多的性能问题。
在某些前提下,有些场景可能会很有趣:
- 2 个文件组:数据和索引
- 3 个文件组:只读表、读写表、索引
- 多个文件组:只读、读写、索引、键表 1、键表 2、...
您必须分析您的环境来确定文件组是否有助于满足您的 SQL Server 增长、使用和性能需求。
移动到多个文件组的一些关键指标(从本文):
- 当磁盘排队导致应用程序和用户体验问题时
- 如果是这种情况,请考虑利用带有新文件组的额外磁盘驱动器来容纳 IO 密集型表
- 当特定表占数据库的 10% 或更多时
- 如果是这种情况,请考虑将这些特别大的表移动到单独的底层磁盘驱动器上的单独文件组中
- 根据表大小与其余表的比例,考虑为单个表构建一个文件组
- 当大型表上的非聚集索引和数据空间相等时
- 如果是这种情况,请考虑将数据和聚集索引与非聚集索引分开
- 当数据库中只读数据和读写数据的百分比几乎相等时
- 如果是这种情况,请考虑将只读数据拆分到单独的文件组中,作为读写数据
- 当没有足够的时间进行数据库维护时
- 如果是这种情况,请考虑将大表拆分为不同底层磁盘上的单独文件组,并并行执行维护
- 当业务或应用程序发生重大变化且数据将以更快的速度增长时
- 如果是这种情况,请考虑与用户合作,了解潜在的增长
- 当归档数据与生产数据位于同一数据库中时
- 如果是这种情况,请考虑使用单独的文件组或本技巧中的一种或多种技术 - 在 SQL Server 中归档数据
如果您发现文件组可以提高数据库的性能,请在生产服务器上实施更改之前,在临时环境中编写代码并测试该过程。在实施更改之前准备一些测量值,并比较前后情况。由于这些过程可能非常耗费资源和时间,请在维护期间执行这些过程。
不要忘记,在创建新对象(表和索引)时,请确保在正确的文件组中创建对象以确保预期的性能,并定期验证数据库对象是否在正确的文件组中并根据需要进行更正。