मैं इस स्क्रिप्ट का उपयोग करता हूं। कृपया ध्यान दें कि मैं आपको डीएमवी के बारे में पढ़ने की सलाह दूंगा जिसका मैं यहां उपयोग कर रहा हूं, वे SQL2005+ में एक छिपे हुए मणि हैं।
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
CREATE TABLE #FragmentedIndexes
(
DatabaseName SYSNAME
, SchemaName SYSNAME
, TableName SYSNAME
, IndexName SYSNAME
, [Fragmentation%] FLOAT
)
INSERT INTO #FragmentedIndexes
SELECT
DB_NAME(DB_ID()) AS DatabaseName
, ss.name AS SchemaName
, OBJECT_NAME (s.object_id) AS TableName
, i.name AS IndexName
, s.avg_fragmentation_in_percent AS [Fragmentation%]
FROM sys.dm_db_index_physical_stats(db_id(),NULL, NULL, NULL, 'SAMPLED') s
INNER JOIN sys.indexes i ON s.[object_id] = i.[object_id]
AND s.index_id = i.index_id
INNER JOIN sys.objects o ON s.object_id = o.object_id
INNER JOIN sys.schemas ss ON ss.[schema_id] = o.[schema_id]
WHERE s.database_id = DB_ID()
AND i.index_id != 0
AND s.record_count > 0
AND o.is_ms_shipped = 0
DECLARE @RebuildIndexesSQL NVARCHAR(MAX)
SET @RebuildIndexesSQL = ''
SELECT
@RebuildIndexesSQL = @RebuildIndexesSQL +
CASE
WHEN [Fragmentation%] > 30
THEN CHAR(10) + 'ALTER INDEX ' + QUOTENAME(IndexName) + ' ON '
+ QUOTENAME(SchemaName) + '.'
+ QUOTENAME(TableName) + ' REBUILD;'
WHEN [Fragmentation%] > 10
THEN CHAR(10) + 'ALTER INDEX ' + QUOTENAME(IndexName) + ' ON '
+ QUOTENAME(SchemaName) + '.'
+ QUOTENAME(TableName) + ' REORGANIZE;'
END
FROM #FragmentedIndexes
WHERE [Fragmentation%] > 10
DECLARE @StartOffset INT
DECLARE @Length INT
SET @StartOffset = 0
SET @Length = 4000
WHILE (@StartOffset < LEN(@RebuildIndexesSQL))
BEGIN
PRINT SUBSTRING(@RebuildIndexesSQL, @StartOffset, @Length)
SET @StartOffset = @StartOffset + @Length
END
PRINT SUBSTRING(@RebuildIndexesSQL, @StartOffset, @Length)
EXECUTE sp_executesql @RebuildIndexesSQL
DROP TABLE #FragmentedIndexes
यह भी ध्यान रखें कि यह स्क्रिप्ट कुछ समय तक चल सकती है और आपकी टेबल तक पहुंच को अवरुद्ध कर सकती है। जब तक आपके पास एंटरप्राइज़ संस्करण न हों, इंडेक्स का पुनर्निर्माण करते समय SQL तालिका को लॉक कर सकता है। यह इंडेक्स डीफ़्रैग समाप्त होने तक इंडेक्स का उपयोग करके उस तालिका में सभी प्रश्नों को अवरुद्ध कर देगा। इस प्रकार केवल रखरखाव विंडो के दौरान परिचालन घंटों के दौरान इंडेक्स पुनर्निर्माण चलाने की सलाह नहीं दी जाती है। यदि आप एंटरप्राइज़ संस्करण चला रहे हैं तो आप अनुक्रमणिका को ऑनलाइन डीफ़्रैग करने के लिए ONLINE=ON विकल्प का उपयोग कर सकते हैं। यह अधिक स्थान का उपयोग करेगा लेकिन डीफ़्रैग ऑपरेशन के दौरान आपकी तालिकाओं को अवरुद्ध/लॉक नहीं किया जाएगा।
अगर आपको और जानकारी चाहिए तो चिल्लाएं।
अपडेट किया गया:
यदि आप इस क्वेरी को एक छोटे डेटाबेस पर चला रहे हैं तो आप शायद sys.dm_db_index_physical_stats पर कॉल में 'विस्तृत' पैरामीटर का उपयोग कर सकते हैं। यह शायद इंडेक्स की अधिक विस्तृत जांच है। टिप्पणियों में चर्चा यह भी बताएगी कि बहुत बड़ी तालिकाओं पर यह संभवतः एक नमूना स्कैन करने के लायक है क्योंकि इससे इंडेक्स स्कैन करने के लिए आवश्यक समय को कम करने में मदद मिलेगी।