Missing Index در SqlServer
این اسکریپت به ایندکسهای گمشدهای مربوط میشود که SQL Server آنها را شناسایی کرده است. SQL، کوئریها را ردیابی میکند و پیشنهادهایی برای ایجاد ایندکسهایی ارائه میدهد که میتواند باعث بهبود عملکرد شود. اما نباید بدون بررسی دقیق، مستقیماً از این پیشنهادات استفاده کرده و تمامی ایندکسهای توصیه شده را ایجاد کنید. بهینهسازی عملکرد یک فرآیند دقیق و هنری است که نیاز به تجربه و تمرین دارد. این اطلاعات باید با دقت ارزیابی شده و به عنوان یک DBA به صورت مرحله به مرحله پیادهسازی شود.
ستونهایی که نیاز به توجه دارند شامل AvgUserImpact (تأثیر متوسط بر کاربر)، UniqueCompiles (تعداد کامپایلهای منحصربهفرد)، UserSeeks (تعداد جستجوهای کاربر) و UserScans (تعداد اسکنهای کاربر) هستند. نباید تنها به یک ستون مانند AvgUserImpact توجه کنید. اگرچه ممکن است SQL پیشنهاد دهد که افزودن یک ایندکس میتواند عملکرد را تا 99 درصد بهبود بخشد، مهم است که بررسی کنیم این ایندکس چند بار مورد استفاده قرار میگیرد. بهتر است ایندکسی با تأثیر متوسط کمتر ولی با استفاده بیشتر را پیادهسازی کنید تا ایندکسی که تأثیر زیادی دارد اما بسیار کم استفاده میشود.
قبل از افزودن ایندکس جدید، حتماً ایندکسهای فعلی جدول را مرور کنید. ممکن است بتوانید با افزودن یک فیلد به ایندکسهای موجود به بهبود عملکرد دست یابید، بدون اینکه نیاز به ایجاد ایندکس جدید باشد. به خاطر داشته باشید که ایندکسها به خودی خود بار اضافی به پایگاه داده وارد میکنند، بنابراین باید با دقت و بررسی کامل انتخاب شوند.
-- Missing Index Script SELECT db.[name] AS [DatabaseName] ,OBJECT_NAME(id.[object_id], db.[database_id]) AS [ObjectName] ,id.[statement] AS [FullyQualifiedObjectName] ,id.[equality_columns] AS [EqualityColumns] ,id.[inequality_columns] AS [InEqualityColumns] ,id.[included_columns] AS [IncludedColumns] ,gs.[unique_compiles] AS [UniqueCompiles] ,gs.[user_seeks] AS [UserSeeks] ,gs.[user_scans] AS [UserScans] ,gs.[last_user_seek] AS [LastUserSeekTime] ,gs.[last_user_scan] AS [LastUserScanTime] ,gs.[avg_total_user_cost] AS [AvgTotalUserCost] -- Average cost of the user queries that could be reduced by the index in the group. ,gs.[avg_user_impact] AS [AvgUserImpact] -- The value means that the query cost would on average drop by this percentage if this missing index group was implemented. ,gs.[user_seeks] * gs.[avg_total_user_cost] * (gs.[avg_user_impact] * 0.01) AS [IndexAdvantage] ,'CREATE INDEX [IX_' + OBJECT_NAME(id.[object_id], db.[database_id]) + '_' + REPLACE(REPLACE(REPLACE(ISNULL(id.[equality_columns], ''), ', ', '_'), '[', ''), ']', '') + CASE WHEN id.[equality_columns] IS NOT NULL AND id.[inequality_columns] IS NOT NULL THEN '_' ELSE '' END + REPLACE(REPLACE(REPLACE(ISNULL(id.[inequality_columns], ''), ', ', '_'), '[', ''), ']', '') + '_' + LEFT(CAST(NEWID() AS [nvarchar](64)), 5) + ']' + ' ON ' + id.[statement] + ' (' + ISNULL(id.[equality_columns], '') + CASE WHEN id.[equality_columns] IS NOT NULL AND id.[inequality_columns] IS NOT NULL THEN ',' ELSE '' END + ISNULL(id.[inequality_columns], '') + ')' + ISNULL(' INCLUDE (' + id.[included_columns] + ')', '') AS [ProposedIndex] ,CAST(CURRENT_TIMESTAMP AS [smalldatetime]) AS [CollectionDate] FROM [sys].[dm_db_missing_index_group_stats] gs WITH (NOLOCK) INNER JOIN [sys].[dm_db_missing_index_groups] ig WITH (NOLOCK) ON gs.[group_handle] = ig.[index_group_handle] INNER JOIN [sys].[dm_db_missing_index_details] id WITH (NOLOCK) ON ig.[index_handle] = id.[index_handle] INNER JOIN [sys].[databases] db WITH (NOLOCK) ON db.[database_id] = id.[database_id] WHERE db.[database_id] = DB_ID() ORDER BY ObjectName, [IndexAdvantage] DESC OPTION (RECOMPILE);