Лучший подход для переиндексации - PullRequest
2 голосов
/ 13 июля 2009

Я пытаюсь уменьшить фрагментацию во всех индексах для базы данных, работающей на SQL Server 2005. В настоящее время я пытаюсь использовать ALTER INDEX в сочетании с sp_MSforeachtable, чтобы применить его ко всем индексам для всех таблиц:

sp_MSforeachtable "ALTER INDEX ALL ON ? REBUILD;"

Но по какой-то причине это не всегда работает? Если я попробую его для одного индекса или для всех индексов для одной таблицы, тогда фрагментация будет очищена, и, похоже, только при применении ее ко всей базе данных у меня возникают проблемы.

Ранее я мог использовать DBCC DBREINDEX, но BOL заявляет, что он будет удален в следующей версии SQL Server, поэтому я не хочу его использовать.

Может кто-нибудь дать мне какой-нибудь совет о том, как лучше всего очистить все индексы в базе данных?

Спасибо

Ответы [ 4 ]

5 голосов
/ 13 июля 2009

Если вы хотите полностью автоматизировать обслуживание индекса SQL Server, тогда я настоятельно рекомендую вам проверить для этого хранимую процедуру Мишель Аффорд.

Сценарий индексации дефрагментации V4.1

Это то, что я считаю лучшим сценарием обслуживания индекса, который я когда-либо читал.

Одна из лучших функций этого сценария заключается в том, что вы можете настроить пороговые значения, которые вы используете, чтобы определить, нужно ли REBUILD или REORGANIZE заданный индексный элемент.

Он также предоставляет возможность ограничить количество ядер ЦП, используемых процедурой. Отличный вариант, если вы собираетесь запустить сценарий в загруженной производственной базе данных.

Предупреждение. Как и в случае со всем доступным в Интернете кодом, обязательно тщательно его протестируйте перед использованием в производственной среде. Вы также, скорее всего, захотите включить свои собственные настройки и функции.

3 голосов
/ 13 июля 2009

Ознакомьтесь со статьей и прилагаемым примером сценария для решения этой задачи на SQL Fool (веб-сайт Мишель Аффорд):

http://sqlfool.com/2009/06/index-defrag-script-v30/

Это довольно хорошее решение, чтобы справиться с этим раз и навсегда!

Рекомендуется реорганизовать ваш индекс, если у вас есть 5-30% фрагментации, и перестраивать его, только если он имеет более 30% фрагментации. Вы можете легко использовать эти пороговые значения или указать свой собственный, используя этот скрипт.

Марк

1 голос
/ 13 июля 2009

Или вы можете использовать скрипт перестройки индекса Microsoft, найденный здесь http://msdn.microsoft.com/en-us/library/ms188917.aspx

    -- Ensure a USE <databasename> statement has been executed first.
SET NOCOUNT ON;
DECLARE @objectid int;
DECLARE @indexid int;
DECLARE @partitioncount bigint;
DECLARE @schemaname nvarchar(130); 
DECLARE @objectname nvarchar(130); 
DECLARE @indexname nvarchar(130); 
DECLARE @partitionnum bigint;
DECLARE @partitions bigint;
DECLARE @frag float;
DECLARE @command nvarchar(4000); 
-- Conditionally select tables and indexes from the sys.dm_db_index_physical_stats function 
-- and convert object and index IDs to names.
SELECT
    object_id AS objectid,
    index_id AS indexid,
    partition_number AS partitionnum,
    avg_fragmentation_in_percent AS frag
INTO #work_to_do
FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL , NULL, 'LIMITED')
WHERE avg_fragmentation_in_percent > 10.0 AND index_id > 0;

-- Declare the cursor for the list of partitions to be processed.
DECLARE partitions CURSOR FOR SELECT * FROM #work_to_do;

-- Open the cursor.
OPEN partitions;

-- Loop through the partitions.
WHILE (1=1)
    BEGIN;
        FETCH NEXT
           FROM partitions
           INTO @objectid, @indexid, @partitionnum, @frag;
        IF @@FETCH_STATUS < 0 BREAK;
        SELECT @objectname = QUOTENAME(o.name), @schemaname = QUOTENAME(s.name)
        FROM sys.objects AS o
        JOIN sys.schemas as s ON s.schema_id = o.schema_id
        WHERE o.object_id = @objectid;
        SELECT @indexname = QUOTENAME(name)
        FROM sys.indexes
        WHERE  object_id = @objectid AND index_id = @indexid;
        SELECT @partitioncount = count (*)
        FROM sys.partitions
        WHERE object_id = @objectid AND index_id = @indexid;

-- 30 is an arbitrary decision point at which to switch between reorganizing and rebuilding.
        IF @frag < 30.0
            SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REORGANIZE';
        IF @frag >= 30.0
            SET @command = N'ALTER INDEX ' + @indexname + N' ON ' + @schemaname + N'.' + @objectname + N' REBUILD';
        IF @partitioncount > 1
            SET @command = @command + N' PARTITION=' + CAST(@partitionnum AS nvarchar(10));
        EXEC (@command);
        PRINT N'Executed: ' + @command;
    END;

-- Close and deallocate the cursor.
CLOSE partitions;
DEALLOCATE partitions;

-- Drop the temporary table.
DROP TABLE #work_to_do;
GO

Я использую этот скрипт вместе с агентом SQL Server для автоматизации задачи. Надеюсь, это поможет.

0 голосов
/ 13 июля 2009

Самый безопасный и переносимый способ - сбросить индексы и добавить их заново.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...