如果你像我一样,那么你就会有一个在适当位置的SQL Agent任务需要重建和重新组织,而实际上只有你数据库中的索引需要这样的操作。如果你依赖于Microsoft SQL Server中的标准技术维护计划,那么重建所有索引的焦土政策将产生。更确切地说,无论这些操作是否要求被用到具体的索引中,索引的重建以及对所有锁和日志的搅拌都会发生。这就是为什么可以说大多数人都会推出自己的索引维护解决方案。这也正是我最大的烦恼之一。无论如何,通过只维护成为碎片的索引,相对于你数据库中的表/索引,统计数据不能发生全面自动更新。我们所需要的正是对我们的SQL Server实例上的每一个数据库采取更新所有统计这样一个快速的解决方案。
在你开始操作前,我必须声明一个事实,那就是你在自己的数据库上有AUTO_UPDATE_STATISTICS ON,但请记住那并不意味着它们正在更新!
可能你对此会很不屑。那么请稍微思考这个问题。当处在下面的情况时,SQL Server的引擎将会自动更新:
l 当数据刚被添加到一张空表时
(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)l 当统计是上次搜集的并且从搜集开始,统计数据对象的主要字段每500秒增长一次时,这张表的记录超过500。
l 当统计数据是上次搜集的,并且,从上次统计数据搜集日期起统计数据对象的主要字段按照每500秒加上行数的20%更改时。
在这个标准下,有很多这样的情况:当潜在的数据以这样一种方式或者层次变化时,存在于一个索引中的统计不能正确反映数据库中真实的数据。正因为如此,你不能仅仅依赖于引擎来使你的统计保持检查和更新成当前的状态。这是一个简单的代码块,它将迭代处理你的数据库以此来建立sp_updatestats命令,该命令随后将被复制粘贴到一个新的查询窗口来执行。这些代码将与所有当前的和先前的SQL Server版本一道回到SQL 7.0工作。
(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/) DECLARE @SQL VARCHAR(1000)
DECLARE @DB sysname
DECLARE curDB CURSOR FORWARD_ONLY STATIC FOR
SELECT [name]
FROM sys..sysdatabases
WHERE [name] NOT IN ('model', 'tempdb')
ORDER BY [name]
OPEN curDB
FETCH NEXT FROM curDB INTO @DB
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @SQL = 'USE [' + @DB +']' + CHAR(13) + 'EXEC sp_updatestats' + CHAR(13)
PRINT @SQL
FETCH NEXT FROM curDB INTO @DB
END
CLOSE curDB
DEALLOCATE curDB
在我的测试数据库中,这些代码产生了下面的结果:
图1
接下来我们把复制这个文本,把它粘贴到SQL Server管理套件的一个查询窗口,然后针对这个实例执行它。另一种方法是,你可以选择只针对select数据库执行它,但这完全取决于你。
USE [Dummy]
EXEC sp_UpdateStats
USE [master]
EXEC sp_UpdateStats
USE [msdb]
EXEC sp_UpdateStats
USE [MSSQLTips]
EXEC sp_UpdateStats
USE [MSSQLTips_DUPE]
EXEC sp_UpdateStats
USE [Northwind]
EXEC sp_UpdateStats
USE [Sitka]
EXEC sp_UpdateStats
USE [Utility]
EXEC sp_UpdateStats
我已经提供了上面执行的SQL语句搜集产生的输出结果实例。正如你看到的,引擎仍然会审查这些统计,看看它们是否需要更新。它将忽略哪些可以接受的,只更新那些要求这种操作的统计。我可以向你保证,上面列出的每一个数据库都把AUTO_UPDATE_STATISTICS和AUTO_CREATE_STATISTICS设置成ON,但下面的结果表明统计数据将变成过时的。
图2