Bee*_*ems 7 sql-server sql-server-2008-r2
我们有一个 SQL 数据库,可以存储大约 3000 台 PC 的应用程序使用日志。这些 PC 每天将使用数据发送到 SQL 服务器大约 10-20 次。我们过去只存储最近 60 天的应用程序使用情况,但客户要求我们不再清除数据。现在我们有大约一年的数据(大约 6,000,000 行),SQL 数据库遇到了一些性能问题。请注意,这并不重要,但远远超过我们拥有的任何其他数据库。每小时都会添加大量记录(应用程序打开记录),并且最多在几个小时内该记录将在关联的应用程序关闭时更新一次。您可以通过 SQL 活动监视器看到这些更新需要相当长的时间才能完成。
UPDATE 查询很简单:
SELECT TOP 1 f_ID
from tb_applicationusage
WHERE f_application = 'xxxxxxx' AND
f_computername = 'xxxxxxxxx' AND
f_endtime IS NULL
ORDER BY f_starttime DESC
Run Code Online (Sandbox Code Playgroud)
实际上,它为尚未关闭关联应用程序的特定机器查找最近匹配的应用程序启动。我想不出更有效的方式来运行查询,所以我正在考虑以下替代方案:
移动到两个数据库:
我不是 SQL 专家,所以我可能忽略了这种方法的一些缺点。目标是让 SQL 代理作业每晚将完成的记录移动到最终数据库。然后,当客户想要运行他们的月度报告时,我可以让该报告仅查询最终数据库而不是工作数据库。在工作数据库中查询可能只有 10,000 条记录,而不是 6,000,000 条记录,它会更快地工作似乎是合乎逻辑的。但同样,这似乎很简单,我可能遗漏了一些明显的东西。
版本:Microsoft SQL Server 2008 R2
两件事情
你实际上并没有说你在桌子上有一个索引——我希望这能解决你的问题。f_application、f_computername、f_endtime、f_starttime 上的索引应该使您的更新时间很小,只有 6mill 记录。
如果您想拆分它,请不要按照您描述的方式进行操作,请为您在当前表之前使用的打开但未关闭的记录创建一个表。然后当某些东西“更新”时,从那个临时表中删除它并将它插入到你的大表中。 以这种方式使用临时表被认为是一种领先/最佳实践 - 将表任意分成两部分总是一场噩梦
你可以做得比两个数据库更好。在对部分旧数据进行分片之前,您应该在现有数据库中查看两件事:
选择一个好的聚集索引。要使聚集索引很好地处理这些数据,您应该遵循三个规则:
如果时间戳增加(即:)f_starttime,这可能对索引中的第一个字段有益,只要它也是要求 #3 中指示的关闭记录的一部分。添加唯一或几乎唯一标识记录所需的任何其他字段。请注意,您仍然可以为表使用标识列。只是不要将它用作聚集索引中的第一列。根据问题中的 sql 代码,我可能会使用f_starttime, f_computername, f_application, f_ID.
即使您使用另一个答案中建议的临时表,这些索引更改仍然可能是一个好主意。
将已完成的记录与打开的记录分开的另一个建议也很好。但是,即使有这个建议,索引和表分区也可以帮助完成记录的表大小变大。只有在所有这些选项都失败后,您才能开始考虑将旧数据分片到单独的(链接的)数据库。
不过,确实,Sql Server 可以轻松处理 600 万条记录,而无需使用这些技巧(不过,更改索引可能仍然值得)。您确定为此正确配置了服务器吗?您也可以简单地将 RAM 添加到服务器。
最后,将报告数据库与实时处理数据库分开也是很常见的,这完全不是一件坏事。我们有时称其为“数据仓库”,尽管这也经常涉及架构更改和用于移动数据的 SSIS 过程。这是一个很好的特性,因为它可以防止数据分析查询中的意外错误导致生产中的性能问题。您最好通过将数据库镜像/日志传送到只读从站,或者最近通过 AlwaysOn 可用性组来最好地完成此操作。
| 归档时间: |
|
| 查看次数: |
234 次 |
| 最近记录: |