使用Ola Hallengren的IndexOptimize脚本遇问题:作业成功但未维护索引
解决Ola Hallengren IndexOptimize脚本未执行索引重建/重组的问题
我来帮你排查这个问题——作业执行成功但没动索引,大概率是脚本没找到符合优化条件的索引,或者参数设置有细微问题。先看你给出的执行脚本:
USE TestDBA EXEC [OlaH].[usp_IndexOptimize] @Databases = 'USER_DATABASES', @FragmentationLow = NULL, @FragmentationMedium = 'INDEX_REORGANIZE,INDEX_REBUILD_ONLINE,INDEX_REBUILD_OFFLINE', @FragmentationHigh = 'INDEX_REBUILD_ONLINE,INDEX_REBUILD_OFFLINE', @FragmentationLevel1 = 5, @FragmentationLevel2 = 30, @PageCountLevel = 0, @SortInTempdb = 'Y', @MaxDOP = NULL, @FillFactor = NULL, @PadIndex = NULL, @LOBCompaction = 'Y', @UpdateStatistics = 'ALL', @OnlyModifiedStatistics = 'Y', @StatisticsSample = NULL, @StatisticsResample = 'N', @PartitionLevel = 'Y', @MSShippedObjects = 'Y', @Indexes = NULL, @TimeLimit = 360, @Delay = NULL, @WaitAtLowPriorityMaxDuration = 5, @WaitAtLowPriorityAbortAfterWait = 'SELF', @LockTimeout = NULL, @LogToTable = 'N', @Execute = 'Y'
下面是几个排查方向,按优先级来:
1. 开启日志记录,直接看脚本到底做了什么
你现在把@LogToTable设为了'N',完全看不到脚本的执行细节。先把这个参数改成'Y',重新运行作业,然后去查询TestDBA.OlaH.CommandLog(如果部署时用的是OlaH schema的话),里面会记录脚本扫描了哪些数据库、哪些索引,以及为什么没执行优化操作——比如“索引碎片率低于阈值”“页数太少”之类的信息,这是最直接的排查依据。
2. 手动检查有没有符合条件的索引
脚本只会处理碎片率和页数达标的索引,你可以跑下面的查询,看看用户数据库里有没有符合你设置的5%-30%(中等碎片)或>30%(高碎片)条件的索引:
SELECT dbs.name AS 数据库名, t.name AS 表名, i.name AS 索引名, CAST(ips.avg_fragmentation_in_percent AS DECIMAL(5,2)) AS 碎片率百分比, ips.page_count AS 索引页数 FROM sys.dm_db_index_physical_stats(NULL, NULL, NULL, NULL, 'DETAILED') ips JOIN sys.tables t ON ips.object_id = t.object_id JOIN sys.indexes i ON ips.object_id = i.object_id AND ips.index_id = i.index_id JOIN sys.databases dbs ON ips.database_id = dbs.database_id WHERE dbs.database_id > 4 -- 排除系统数据库(master/model/msdb/tempdb) AND ips.avg_fragmentation_in_percent >= 5 -- 你的@FragmentationLevel1阈值 AND ips.page_count >= 0 -- 你的@PageCountLevel设置 ORDER BY ips.avg_fragmentation_in_percent DESC;
如果这个查询返回空结果,那说明确实没有符合条件的索引,脚本自然不会执行任何操作。
3. 调整参数缩小范围,排除干扰
- 先关掉系统对象扫描:你设置了
@MSShippedObjects = 'Y',会让脚本扫描用户数据库里的系统对象,但这些一般不需要优化。暂时改成'N',专注于你自己的业务表索引。 - 指定单个数据库测试:把
@Databases = 'USER_DATABASES'改成你具体的用户数据库名(比如@Databases = 'YourBusinessDB'),排除脚本识别用户数据库时可能出现的问题。 - 确认页数阈值的影响:虽然你把
@PageCountLevel设为0,但SQL Server对页数极少的索引(比如1页)的碎片统计不准确,Ola的脚本可能会自动跳过这些索引。如果你的索引大多是小索引,这也会导致没有优化操作。
4. 检查作业的执行上下文
确认你的SQL Agent作业步骤,是不是在正确的数据库环境下执行?虽然你写了USE TestDBA,但如果作业步骤的“数据库”选项设成了其他库(比如master),也可能有潜在问题——不过一般来说USE语句会覆盖这个设置,但最好确认一下。
按上面的步骤排查,应该能很快找到问题所在。
内容的提问来源于stack exchange,提问作者Ap9_Jacka
相关产品推荐
相关产品推荐

