2012-07-02 7 views
5

Tôi đang làm việc để cung cấp phương pháp cho phép cập nhật hàng loạt các bảng của chúng tôi (lớn hơn 1M hàng mới hoặc cập nhật mỗi lần cập nhật) và quan tâm đến việc giảm chỉ mục hiện tại và tạo lại chúng sau khi cập nhật.Tự động thả và tạo lại các chỉ mục hiện tại

Tôi đã tự hỏi nếu có ai có kịch bản để cung cấp khớp nối lỏng lẻo của các hoạt động này sao cho các chỉ mục thay đổi theo thời gian, quá trình cập nhật không thay đổi.

Có vẻ như đây là một trong những điều mà cộng đồng đã có thể giải quyết được.

+2

Vui lòng chỉ định RDBMS mà bạn đang nhắm mục tiêu bằng cách thêm thẻ thích hợp (Oracle, SQL Server, MySQL, v.v.). Có _will_ là câu trả lời tận dụng lợi thế của các tính năng ngôn ngữ hoặc sản phẩm không được hỗ trợ phổ biến. Cũng bằng cách gắn thẻ nó với một RDBMS cụ thể, câu hỏi của bạn có thể nhận được sự chú ý từ những người phù hợp hơn để trả lời câu hỏi của bạn. – Ben

Trả lời

10

Tôi có tập lệnh mà tôi sử dụng để truy vấn các bảng hệ thống để nắm bắt tất cả các chỉ mục không được nhóm và tắt rồi xây dựng lại sau khi hoàn thành. Dưới đây là để sử dụng trên phiên bản tiêu chuẩn, nếu bạn đang ở trên doanh nghiệp, tôi sẽ thêm tùy chọn ONLINE.

Disable

DECLARE @sql AS VARCHAR(MAX); 
SET @sql = ''; 
SELECT 
    @sql = @sql + 'ALTER INDEX [' + i.name + '] ON [' + o.name + '] DISABLE; ' 
FROM sys.indexes AS i 
JOIN sys.objects AS o ON i.object_id = o.object_id 
WHERE i.type_desc = 'NONCLUSTERED' 
AND o.type_desc = 'USER_TABLE' 

EXEC (@sql) 

Rebuild

DECLARE @sql AS VARCHAR(MAX); 
SET @sql = ''; 
SELECT 
    @sql = @sql + 'ALTER INDEX [' + i.name + '] ON [' + o.name + '] REBUILD WITH (FILLFACTOR = 80); ' 
FROM sys.indexes AS i 
JOIN sys.objects AS o ON i.object_id = o.object_id 
WHERE i.type_desc = 'NONCLUSTERED' 
AND o.type_desc = 'USER_TABLE' 

EXEC (@sql); 

Tôi thích phương pháp này vì nó là rất tùy biến như bạn có thể loại trừ/bao gồm các bảng nhất định dựa trên các điều kiện cũng như tránh một con trỏ. Ngoài ra, bạn có thể thay đổi EXEC thành PRINT và xem mã sẽ thực thi và chạy theo cách thủ công.

Điều kiện để loại trừ một bảng

AND o.name NOT IN ('tblTest','tblTest1'); 
+1

Tuyệt vời! chỉ cần đảo ngược Not IN. Dễ dàng hơn nhiều so với việc thả và tạo ra thứ mà tôi đang cố gắng làm –

+1

Bạn cũng có thể sử dụng 'sys.tables' thay vì' sys.objects' và tự lưu lại để chỉ định 'WHERE o.type_desc = 'USER_TABLE'' mọi lúc .... –

4
EXEC sp_MSforEachTable 'ALTER INDEX ALL ON ? DISABLE' 

EXEC sp_MSforEachTable 'ALTER INDEX ALL ON ? REBUILD' 

là tất cả các bạn cần nếu bạn muốn làm điều đó cho tất cả các bảng và mỗi chỉ mục.

+0

Tôi gặp vấn đề với nó. Bảng bị vô hiệu hóa Chỉ số nhóm không thể nhận được bất kỳ hàng nào được chèn vào, khi bảng bị vô hiệu hóa. – Stoleg

+0

Vui lòng đặt câu hỏi này dưới dạng câu hỏi độc lập. Có quá ít thông tin ... – fancyPants

+0

'INSERT INTO' không thành công trên một bảng có chỉ số nhóm bị vô hiệu hóa. Các hàng dữ liệu trong một bảng với chỉ số nhóm bị vô hiệu hóa chỉ có sẵn cho các hoạt động thả hoặc xây dựng lại. – Stoleg