Tho*_*hom 5 performance sql-server maintenance
我正在处理应用程序的 SQL Server 数据库中的问题。此应用程序用于医疗保健,我只维护数据库,我不创建应用程序。
一段时间后,客户面临着他们的表上转发记录的问题。我创建了一个存储过程,通过创建聚集索引并再次删除它来修复这些转发的记录,有效地重新组织表并修复转发的记录。
我当前脚本的工作方式如下:
#Forwarded_Records
用来自sys.dm_db_index_physical_stats
、sys.indexes
和 的信息填充表 ( )
sys.columns
。这将用包含转发记录和有关其索引的信息(包括离线/在线可用性)的表填充该表。
一旦表被填满,存储过程将检查窗口中是否还有时间做其他工作。如果有,它将从 forwarded_records 表中的第一条记录开始,并开始创建/删除聚集索引。
一旦修复了所有记录,它将开始重新填充 forwarded_records 表并搜索包含转发记录的新表。这将再次开始循环。
我面临以下问题:
现在我的问题是什么?
我怎样才能改进这个过程,使它更有效。目前它在第一个周期非常有效并且修复了所有转发的记录。但是从第二个周期开始,它只会花更多的时间在“查找”转发记录上而不是修复它们(找到它们需要 45 分钟,而修复它们只需要 2 分钟)。
我的情况有没有更好的方法?我应该每天花 45 分钟来理所当然地找到它们,还是我最好做所有表而不是搜索实际需要修复的表。
感谢您的帮助。
(StackExchange 上的第一篇文章,尽量保持建设性。如果这个问题需要编辑,请帮忙)
SQL Server 不会保留转发记录数量的“统计信息”。要返回它必须访问物理表页的数量。如果表很大,则可能需要一段时间。
也就是说,您可以在模式下查询sys.dm_db_index_physical_statsSAMPLED
。这将为您提供基于基表 1% 样本的转发记录数的估计值。
或者,您可以将更新数量(请参阅sys.dm_db_index_usage_stats)与每个表上转发的记录数量相关联。假设如果每 10 次更新都会导致转发,那么您可以通过查看执行的更新数量是否比您的阈值高 10 倍来检查表是否超出了您的阈值。查询 sys.dm_db_index_usage_stats 是即时的。但是,每次服务器重新启动时,它都会从新开始累积。
我仍然会定期(可能每月一次)运行 sys.dm_db_index_physical_stats,以确保该比率仍然准确。
要真正删除转发的记录,您可以使用ALTER TABLE dbo.test REBUILD WITH(ONLINE=ON);
,但这也会重建堆表上的所有非聚集索引。这应该比创建和删除聚集索引要快得多,聚集索引会重建所有非聚集索引两次。(该WITH(ONLINE=ON)
条款需要企业版。)
现在,您必须问自己的更大问题是,数据库中是否真的应该有 4000 个堆。一般来说,精心选择的聚集索引将提高整个系统的性能。存储结构“堆”通常只推荐用于插入次数较多、选择、更新或删除次数很少的表。
在典型的 OLTP 环境中,这只适用于日志表。尝试弄清楚是否可以向表中添加聚集索引,这样您的转发痛苦就会消失。(但是,您需要处理碎片问题,但市场上已经有一些好的(且免费)解决方案;例如Ola Hallengren 的脚本)。
归档时间: |
|
查看次数: |
755 次 |
最近记录: |