Ken*_*enD 5 performance sql-server best-practices
这是对先前问题的跟进。我有一个 SQL Server 2008 R2 标准服务器,它包含一个数据库,除了一个大表之外,它本身几乎没有任何东西。
该表有 100 多万行(35 列),并且每天以大约 250,000 行的速度增长。我们需要所有数据都“在线”,并且大多数列需要以某种方式可搜索。桌上的绝大多数活动是阅读;除了INSERT
白天编辑的新数据外,无需更改任何内容。
用户对表执行一系列查询,从简单的查找记录请求到根据一系列条件提取数万行。我们对运行的查询只有有限的控制,性能开始受到影响,即使有索引也是如此。
问题的很大一部分是磁盘 I/O,我们正在通过改造基于 SSD 的阵列来解决这个问题。由于所有数据库文件都将位于这个新阵列上,因此共识是拥有多个数据库文件不会有任何区别,但将表拆分为单独的表可能是可行的方法。
我现在想知道什么是最好的方法。我正在与自己辩论的两个想法:
将表拆分为“层”
INSERT
每天被编辑 的数据然后我会在一夜之间将数据“洗牌”到层级(数据库只能在上午 8 点到晚上 10 点访问,所以我有一个隔夜窗口来处理数据)。
为数据范围创建表
INSERT
放入 2013 年第 2 季度的表中,然后转到 2013 年第 3 季度、2014 年第 4 季度等...如果这可以提高性能,我可以使用文件组使旧表“只读”。
选项 1 对我来说是最容易实现的,但我不确定这是否是一个完全疯狂的想法。选项 2 需要更多的工作来实施和维护,但如果它是此类问题的“最佳实践”,那么我将采用这种方式。
我们将不胜感激地收到任何和所有建议或替代想法 - 我认为这些类型的问题最好在设计时解决。
我对您的情况的第一个问题是标准版是否是给定的,或者您是否有可能升级到企业版。
在 SQL Server 2008 R2 的企业版中,您可以使用分区表。
本质上,他们在后台执行您所描述的手动过程。
引自1:
分区使大型表或索引更易于管理,因为分区使您能够快速有效地管理和访问数据子集,同时保持数据集合的完整性。通过使用分区,诸如将数据从 OLTP 加载到 OLAP 系统之类的操作只需几秒钟,而不是在早期版本的 SQL Server 中需要几分钟和几小时。对数据子集执行的维护操作也能更有效地执行,因为这些操作仅针对所需的数据,而不是整个表。
编辑作为 op 声明 Enterprise 不是一个选项:
使用标准版时,您可以回退到使用分区视图。
与使用方面的主要区别在于您必须为自己维护分区表,并且还必须确保每个新成员表都添加到视图中。
这个想法建立在你的场景 2 上,但你不必关心在哪里插入数据,因为这是由基于成员表中 CHECK-Constraints 的分区视图确定的。
一个很好的例子,见2
对于所有分区方案,您必须确保您选择的分区列适合您的查询和插入行为。
我个人会选择你的第一个选择。如果您使用“DELETE dbo.p1 OUTPUT INTO dbo.p2”模式来移动数据,则不会有太多失败的情况。如果您批量移动大约 10K 行,那么在您所拥有的时间范围内以这种方式移动 250K x 3 行也不应该成为问题。
与更常见的基于日历的分区相比,我看到的优点是您的“分区”保持相同的大小。考虑到您要处理的数据量,基于日历的分区方法在月初效果很好,但在月底可能会明显变慢。
不久前,我与 Kalen Delany 一起在 sqlmag 上写了一篇文章,介绍“随着数据老化,将数据从一个分区移动到另一个分区”方法的优点:http ://sqlmag.com/database-administration/using-table-partitions-归档旧数据 oltp 环境
该文章使用的是企业专用的内置分区功能,但您也可以使用手动多表分区来实现它。
我会尝试将不同的表(分区)放在不同的驱动器上。由于旧分区中的数据仅在停机期间更改,因此您仍然可以在白天将这些文件组标记为只读。或者,您可以使用TRANSACTION ISOLATION READ UNCOMMITTED
或READ COMMITTED SNAPSHOT
隔离。假设您确实不更新数据,后者也应该加快“当前”分区的速度。但即使有更新,它也可能会有所帮助。无论哪种方式,请确保在您的环境中测试性能。(无论如何,请勿UNCOMMITTED
在活动表/分区中使用,因为您读取查询可能最终会看到半写入的行,具体取决于您使用的数据类型。)
归档时间: |
|
查看次数: |
27169 次 |
最近记录: |