2010-03-25 23 views
14

tôi chọn một số chỉ số không clustered từ cơ sở dữ liệu của tôi với những điều sau đây:Disable tất cả các chỉ số không clustered

SELECT sys.objects.name tableName, 
     sys.indexes.name indexName 
FROM sys.indexes 
     JOIN sys.objects ON sys.indexes.object_id = sys.objects.object_id 
WHERE sys.indexes.type_desc = 'NONCLUSTERED' 
     AND sys.objects.type_desc = 'USER_TABLE' 

Tôi muốn chạy sau hơn so với từng kết quả:

ALTER INDEX indexName ON tableName DISABLE 

Làm cách nào để tôi thực hiện việc này? Có cách nào tốt hơn?

EDIT

tôi đang làm điều này với mục đích cắt bỏ bảng, sau đó xây dựng lại với "ALTER INDEX bla ON bảng xây dựng lại". Điều này cần phải được tự động, do đó, giảm và xây dựng lại sẽ là một hoạt động bảo trì cao hơn một chút tôi muốn tránh. Đây có phải là kế hoạch tồi không? Tôi cần một phương tiện làm trống các bảng với chi phí tối thiểu.

+1

Bạn có thể nên tắt chúng vì không có ALTER INDEX ENABLE, chúng sẽ cần được tạo lại. Chúng sẽ không được duy trì nếu bị vô hiệu hóa. –

+2

Nếu bị bỏ, bạn sẽ mất các định nghĩa và sẽ phải nhớ chúng nếu (khi nào) bạn cần tạo lại chúng. Nếu bị tắt, các định nghĩa sẽ được lưu giữ trong bảng hệ thống và bạn không phải lo lắng về việc tạo lại chúng từ đầu. –

+2

@jl bạn có thể kích hoạt lại chỉ mục bằng cách sử dụng ALTER INDEX REBUILD. – kristianp

Trả lời

24

Bạn có thể xây dựng các truy vấn vào một tuyên bố chọn, như vậy:

DECLARE @sql AS VARCHAR(MAX)=''; 

SELECT @sql = @sql + 
'ALTER INDEX ' + sys.indexes.name + ' ON ' + sys.objects.name + ' DISABLE;' +CHAR(13)+CHAR(10) 
FROM 
    sys.indexes 
JOIN 
    sys.objects 
    ON sys.indexes.object_id = sys.objects.object_id 
WHERE sys.indexes.type_desc = 'NONCLUSTERED' 
    AND sys.objects.type_desc = 'USER_TABLE'; 

EXEC(@sql); 

Chars 13 và 10 là những dòng thức ăn chăn nuôi/vận chuyển-lợi nhuận, vì vậy bạn có thể kiểm tra kết quả bằng cách thay thế EXEC với PRINT, và nó sẽ dễ đọc hơn.

+0

Nhưng đặt nó dưới dạng vòng lặp (bảng con trỏ hoặc bảng tạm thời/cấu trúc WHILE), để xử lý từng chỉ mục lần lượt –

+0

Điểm tốt, nhưng vô hiệu hóa các chỉ mục không được nhóm lại quá đắt đến mức cần thiết? –

+1

Điều này chỉ kéo kết quả cuối cùng trong bộ này. Tuyên bố phải là DECLARE @sql AS VARCHAR (MAX) = ''; và lựa chọn nên bắt đầu SELECT @sql = @ sql + 'ALTE ... để nối tất cả các kết quả lại với nhau. Nếu không, rất đẹp. Tôi sẽ thử điều này ngay bây giờ. – spender

3

Tạo biến bảng với các chỉ mục và tên bảng. Sử dụng một vòng lặp để lặp qua chúng, và thực thi một câu lệnh SQL động cho mỗi câu lệnh.

declare @Indexes table 
(
    Num  int identity(1,1) primary key clustered, 
    TableName nvarchar(255), 
    IndexName nvarchar(255) 
) 

INSERT INTO @Indexes 
(
    TableName, 
    IndexName 
) 
SELECT sys.objects.name tableName, 
     sys.indexes.name indexName 
FROM sys.indexes 
     JOIN sys.objects ON sys.indexes.object_id = sys.objects.object_id 
WHERE sys.indexes.type_desc = 'NONCLUSTERED' 
     AND sys.objects.type_desc = 'USER_TABLE' 

DECLARE @Max INT 
SET @Max = @@ROWCOUNT 

SELECT @Max as 'max' 
SELECT * FROM @Indexes 

DECLARE @I INT 
SET @I = 1 

DECLARE @TblName NVARCHAR(255), @IdxName NVARCHAR(255) 

DECLARE @SQL NVARCHAR(MAX) 

WHILE @I <= @Max 
BEGIN 
    SELECT @TblName = TableName, @IdxName = IndexName FROM @Indexes WHERE Num = @I 
    SELECT @SQL = N'ALTER INDEX ' + @IdxName + N' ON ' + @TblName + ' DISABLE;' 

    EXEC sp_sqlexec @SQL  

    SET @I = @I + 1 

END 
0

OTOH nó có thể là tốt hơn giảm khá DISABLE đó (hoặc là nó một lil nhỏ diff cú pháp giữa Oracle và MS SQL? :-) Lý do tôi đề cập đến là tôi nhớ bảng được repopulated và excplicilty denormalized hai lần một ngày và chúng tôi đã DROP-ing tất cả các chỉ mục để buộc DB để xây dựng lại cả hai chỉ số và kế hoạch thực hiện sproc sau khi chúng tôi nạp ngày mới và xây dựng lại tất cả các chỉ mục.

Tất nhiên chúng tôi đã có tập lệnh riêng biệt cho rằng kể từ khi bạn thả chúng, chỉ mục không có trong bảng hệ thống nữa.

+0

Vô hiệu hóa chỉ mục không được nhóm sẽ giữ lại định nghĩa và cho phép tạo lại/xây dựng lại nhanh hơn khoảng 50% sự giảm và tạo. – JNK

0

Sử dụng con trỏ để tập lệnh có nhiều thành ngữ hơn bảng tạm thời (và hơi nhỏ). Để kích hoạt lại các chỉ mục, hãy thay thế DISABLE bằng REBUILD.

DECLARE cur_indexes CURSOR FOR 
SELECT sys.objects.name tableName, 
     sys.indexes.name indexName 
FROM sys.indexes 
     JOIN sys.objects ON sys.indexes.object_id = sys.objects.object_id 
WHERE sys.indexes.type_desc = 'NONCLUSTERED' 
     AND sys.objects.type_desc = 'USER_TABLE' 

DECLARE @TblName NVARCHAR(255), @IdxName NVARCHAR(255) 

DECLARE @SQL NVARCHAR(MAX) 

open cur_indexes 
fetch next from cur_indexes into @TblName, @IdxName 

WHILE @@FETCH_STATUS = 0 
BEGIN 
    SELECT @SQL = N'ALTER INDEX ' + @IdxName + N' ON ' + @TblName + ' DISABLE;' 

    EXEC sp_sqlexec @SQL  

    fetch next from cur_indexes into @TblName, @IdxName 
END 

close cur_indexes 
deallocate cur_indexes 
+0

Bạn đang thiếu từ khóa 'CURSOR' trong dòng 1 tôi tin. 'DECLARE cur_indexes CURSOR FOR' – Zack

+0

được cập nhật, cảm ơn @Zack – kristianp

Các vấn đề liên quan