온라인에서 좋은 리소스를 찾을 수 없었기 때문에 좀 더 실습 연구를 수행했으며 그 연구를 기반으로 구현되는 전체 텍스트 유지 관리 계획을 게시하는 것이 유용 할 것이라고 생각했습니다.
유지 보수가 필요한시기를 결정하는 휴리스틱
기본 목표는 기본 테이블에서 데이터가 발전함에 따라 일관된 전체 텍스트 쿼리 성능을 유지하는 것입니다. 그러나 여러 가지 이유로 매일 밤 각 데이터베이스에 대해 대표적인 전체 텍스트 쿼리 제품군을 시작하고 해당 쿼리의 성능을 사용하여 유지 관리가 필요한시기를 결정하기가 어려울 수 있습니다. 따라서 전체 텍스트 인덱스 유지 관리가 필요하다는 것을 나타내는 휴리스틱으로 매우 빠르게 계산할 수있는 경험 법칙을 만들려고했습니다.
이 탐색 과정에서 시스템 카탈로그는 전체 텍스트 인덱스를 조각으로 나누는 방법에 대한 많은 정보를 제공한다는 것을 알았습니다. 그러나 공식 "조각 %"는 없습니다 ( sys.dm_db_index_physical_stats 를 통한 b- 트리 인덱스의 경우 ). 전체 텍스트 조각 정보를 기반으로 자체 "전체 텍스트 조각화 %"를 계산하기로 결정했습니다. 그런 다음 개발 서버를 사용하여 프로덕션 데이터의 천만 행 사본으로 한 번에 100에서 25,000 행 사이의 임의의 위치를 반복적으로 업데이트하고 전체 텍스트 조각화를 기록하고를 사용하여 벤치 마크 전체 텍스트 쿼리를 수행합니다 CONTAINSTABLE
.
위와 아래 차트에서 볼 수 있듯이 결과는 매우 밝았으며 우리가 만든 조각화 측정 값이 관찰 된 성능과 매우 밀접한 상관 관계가 있음을 보여주었습니다. 이는 생산의 질적 관측과도 관련이 있기 때문에 전체 텍스트 인덱스에 유지 관리가 필요한시기를 결정하기위한 휴리스틱으로 조각화 %를 사용하는 데 충분합니다.
정비 계획
다음 코드를 사용하여 각 전체 텍스트 인덱스에 대한 조각화 %를 계산하기로 결정했습니다. 조각화가 10 % 이상인 사소한 크기의 전체 텍스트 인덱스는 야간 유지 관리를 통해 다시 작성되도록 플래그가 지정됩니다.
-- 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
이러한 쿼리는 다음과 같은 결과를 생성하며,이 경우 전체 텍스트 인덱스가 1MB를 초과하고 10 % 이상 조각화되었으므로 행 1, 6 및 9가 최적 성능을 위해 너무 조각화되어 표시됩니다.
유지 보수 케이던스
우리는 이미 야간 유지 관리 기간이 있으며 조각화 계산은 계산하기가 매우 저렴합니다. 따라서 매일 밤이 검사를 실행 한 다음 필요할 때 10 % 조각화 임계 값을 기준으로 전체 텍스트 인덱스를 실제로 다시 작성하는 더 비싼 작업 만 수행합니다.
리빌드 vs. 재구성 vs. DROP / CREATE
SQL Server가 제공하는 옵션 REBUILD
과 REORGANIZE
옵션은 전체 텍스트 카탈로그 (전체 텍스트 인덱스를 포함 할 수 있음) 전체에 대해서만 사용할 수 있습니다. 레거시 이유로 인해 전체 텍스트 인덱스가 모두 포함 된 단일 전체 텍스트 카탈로그가 있습니다. 따라서 개별 전체 텍스트 인덱스 수준 에서 삭제 ( DROP FULLTEXT INDEX
) 및 다시 만들기 ( CREATE FULLTEXT INDEX
)를 선택했습니다.
논리적으로 전체 텍스트 인덱스를 별도의 카탈로그로 나누고 REBUILD
대신 수행하는 것이 더 이상적 이지만 드롭 / 생성 솔루션은 그 동안 우리에게 효과적입니다.