Tôi không thể tìm thấy bất kỳ tài nguyên tốt nào trên mạng, vì vậy tôi đã thực hiện thêm một số nghiên cứu thực tế và nghĩ rằng sẽ hữu ích khi đăng kế hoạch bảo trì toàn văn kết quả mà chúng tôi đang thực hiện dựa trên nghiên cứu đó.
Heuristic của chúng tôi để xác định khi cần bảo trì
Mục tiêu chính của chúng tôi là duy trì hiệu suất truy vấn toàn văn nhất quán khi dữ liệu phát triển trong các bảng bên dưới. Tuy nhiên, vì nhiều lý do khác nhau, chúng tôi sẽ khó có thể khởi chạy một bộ truy vấn toàn văn đại diện cho mỗi cơ sở dữ liệu của chúng tôi mỗi đêm và sử dụng hiệu suất của các truy vấn đó để xác định khi nào cần bảo trì. Do đó, chúng tôi đang tìm cách tạo ra các quy tắc ngón tay cái có thể được tính toán rất nhanh và được sử dụng như một phương pháp phỏng đoán để chỉ ra rằng bảo trì chỉ mục toàn văn bản có thể được bảo hành.
Trong quá trình khám phá này, chúng tôi thấy rằng danh mục hệ thống cung cấp rất nhiều thông tin về cách bất kỳ chỉ mục toàn văn bản cụ thể nào được chia thành các đoạn. Tuy nhiên, không có tính toán "phân mảnh%" chính thức (vì có các chỉ mục b-cây thông qua sys.dm_db_index_physical_stats ). Dựa trên thông tin phân đoạn toàn văn bản, chúng tôi đã quyết định tính toán "phân mảnh toàn văn bản%" của riêng chúng tôi. Sau đó, chúng tôi đã sử dụng máy chủ dev để liên tục cập nhật ngẫu nhiên bất cứ nơi nào từ 100 đến 25.000 hàng một lần thành bản sao 10 triệu hàng dữ liệu sản xuất, ghi lại phân mảnh toàn văn bản và thực hiện truy vấn toàn văn bản chuẩn bằng cách sử dụng CONTAINSTABLE
.
Các kết quả, như được thấy trong các biểu đồ trên và dưới, rất rõ ràng và cho thấy các biện pháp phân mảnh mà chúng tôi đã tạo ra có mối tương quan rất cao với hiệu suất quan sát được. Vì điều này cũng liên quan đến các quan sát định tính trong sản xuất của chúng tôi, điều này đủ để chúng tôi thoải mái sử dụng% phân mảnh như heuristic để quyết định khi các chỉ mục toàn văn của chúng tôi cần bảo trì.
Kế hoạch bảo trì
Chúng tôi đã quyết định sử dụng mã sau đây để tính% phân mảnh cho mỗi chỉ mục toàn văn. Bất kỳ chỉ mục toàn văn bản nào có kích thước không tầm thường với độ phân mảnh ít nhất 10% sẽ được gắn cờ để được xây dựng lại bởi bảo trì qua đêm của chúng tôi.
-- Compute fragmentation information for all full-text indexes on the database
SELECT c.fulltext_catalog_id, c.name AS fulltext_catalog_name, i.change_tracking_state,
i.object_id, OBJECT_SCHEMA_NAME(i.object_id) + '.' + OBJECT_NAME(i.object_id) AS object_name,
f.num_fragments, f.fulltext_mb, f.largest_fragment_mb,
100.0 * (f.fulltext_mb - f.largest_fragment_mb) / NULLIF(f.fulltext_mb, 0) AS fulltext_fragmentation_in_percent
INTO #fulltextFragmentationDetails
FROM sys.fulltext_catalogs c
JOIN sys.fulltext_indexes i
ON i.fulltext_catalog_id = c.fulltext_catalog_id
JOIN (
-- Compute fragment data for each table with a full-text index
SELECT table_id,
COUNT(*) AS num_fragments,
CONVERT(DECIMAL(9,2), SUM(data_size/(1024.*1024.))) AS fulltext_mb,
CONVERT(DECIMAL(9,2), MAX(data_size/(1024.*1024.))) AS largest_fragment_mb
FROM sys.fulltext_index_fragments
GROUP BY table_id
) f
ON f.table_id = i.object_id
-- Apply a basic heuristic to determine any full-text indexes that are "too fragmented"
-- We have chosen the 10% threshold based on performance benchmarking on our own data
-- Our over-night maintenance will then drop and re-create any such indexes
SELECT *
FROM #fulltextFragmentationDetails
WHERE fulltext_fragmentation_in_percent >= 10
AND fulltext_mb >= 1 -- No need to bother with indexes of trivial size
Các truy vấn này mang lại kết quả như sau và trong trường hợp này, các hàng 1, 6 và 9 sẽ được đánh dấu là quá phân mảnh cho hiệu suất tối ưu vì chỉ mục toàn văn bản là hơn 1MB và bị phân mảnh ít nhất 10%.
Bảo trì nhịp
Chúng tôi đã có một cửa sổ bảo trì hàng đêm và tính toán phân mảnh rất rẻ để tính toán. Vì vậy, chúng tôi sẽ chạy kiểm tra này mỗi đêm và sau đó chỉ thực hiện thao tác đắt tiền hơn là thực sự xây dựng lại một chỉ mục toàn văn khi cần thiết dựa trên ngưỡng phân mảnh 10%.
REBUILD so với REORGANIZE so với DROP / CREATE
SQL Server cung cấp REBUILD
và REORGANIZE
các tùy chọn, nhưng chúng chỉ có sẵn cho một danh mục toàn văn bản (có thể chứa toàn bộ số lượng chỉ mục toàn văn bản). Vì lý do di sản, chúng tôi có một danh mục toàn văn duy nhất chứa tất cả các chỉ mục toàn văn của chúng tôi. Do đó, chúng tôi đã chọn bỏ ( DROP FULLTEXT INDEX
) và sau đó tạo lại ( CREATE FULLTEXT INDEX
) ở cấp chỉ mục toàn văn riêng lẻ.
Có thể lý tưởng hơn khi chia các chỉ mục toàn văn thành các danh mục riêng theo cách hợp lý và thực hiện REBUILD
thay thế, nhưng giải pháp thả / tạo sẽ hoạt động với chúng tôi trong thời gian này.