Полный текстовый индекс SQL Server 2008 никогда не завершается


13

Наш веб-сайт имеет базу данных SQL Server 2008 R2 Express Edition с полнотекстовой индексацией для поиска по нашему веб-сайту. Каждый раз, когда новая запись добавляется или обновляется в одной из проиндексированных таблиц, процесс индексации никогда не завершается.

В течение последних нескольких недель я отслеживал состояние, используя в основном тот же запрос, что и на этом сайте: http://www.sqlmonster.com/Uwe/Forum.aspx/sql-server-search/2155/Why-is-this. -population взятие столь долго

Вот что я вижу, когда запускаю запрос (нажмите для увеличения): Статус полнотекстового индекса

Самые новые записи в индексированных таблицах никогда не завершаются и не доступны для поиска. Несмотря на то, что в таблицах не так много данных, я ждал дни, чтобы увидеть, завершится ли индексация, но ничего не меняется.

Единственный способ успешно завершить индексирование - это перестроить каталог или удалить и заново создать все индексы.

Каждый раз, когда я это делал, одна и та же проблема возвращалась, как только добавлялась первая новая запись.

Вот статистика сервера на всякий случай:

  • Четырехъядерный процессор AMD Opteron 2,34 ГГц
  • 4 ГБ ОЗУ
  • Windows Server 2008 R2 Enterprise SP1 x64
  • SQL Server 2008 R2 Express Edition с расширенными службами x64

Ответы:


6

Я наконец нашел причину своей проблемы!

Я месяцами пытался отследить проблему, но в конце концов сдался, отключил автоматическое отслеживание изменений, просто вручную инициировал добавочную популяцию и продолжил свою жизнь.

Между тем произошла еще одна ноющая ошибка, которую я не мог выследить. Периодически веб-сайт будет выдавать ошибку соединения с БД:

Невозможно открыть базу данных "XXXX", запрошенную при входе в систему. Ошибка входа. Не удалось войти в систему для пользователя 'XXXX'.

Оказалось, что обе эти проблемы имели одно и то же решение. Все, что мне нужно было сделать, это отключить настройку базы данных под названием Auto Close. Для этого просто щелкните правой кнопкой мыши базу данных и выберите Свойства. В окне свойств выберите «Параметры» и установите «Auto Close» в false.

Окно свойств базы данных

Как только я отключил автоматическое закрытие, проблемы с входом в БД исчезли, и автоматическое отслеживание изменений работало отлично.

Еще раз спасибо за помощь всем. Я признателен за это!


3

Любопытно, прошли ли вы шаги по устранению неполадок в BOL для полнотекстовой производительности - http://technet.microsoft.com/en-us/library/ms142560.aspx .

Могу поспорить, что SQL Server пожирает всю вашу память и не позволяет демону фильтра иметь ее, поэтому ваше население работает медленно, так как, скорее всего, придется поменять содержимое на файл подкачки. Вы должны ограничить объем памяти, который может использовать SQL (я думаю, что где-то около 3 ГБ, учитывая ваши текущие системные характеристики - это оставило бы 1 ГБ для FDHost и ОС).


голосование с опережением @Brandon. Прочитайте этот раздел: «Основная причина снижения производительности полнотекстовой индексации - ограничения аппаратных ресурсов:»
MacGyver

2

Вот скрипт, который я создал с использованием курсоров для перестроения и заполнения полных индексов для любой таблицы, в которой есть один для MSSQL2008. Это работает в производственной среде с базами данных, перенесенными с сервера MSSQL 2000. Я отключил отслеживание изменений и просто запустил эту хранимую процедуру через агент SQL Server. Если вы использовали экспресс, вы могли бы использовать сценарий VBS для запуска его через планировщик задач.

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

CREATE PROCEDURE [dbo].[rebuild_repopulate_fulltext] 
AS
BEGIN

Declare @cmdA NVARCHAR(255)
Declare @cmdB NVARCHAR(255)
Declare @cmdC NVARCHAR(255)
DECLARE @Database VARCHAR(255)   
DECLARE @Table VARCHAR(255)  
DECLARE @cmd NVARCHAR(500)  
DECLARE @fillfactor INT 
DECLARE @Catalog VARCHAR(255)
DECLARE @Schema VARCHAR(255)

SET @fillfactor = 90 

DECLARE DatabaseCursor CURSOR FOR  
SELECT name FROM MASTER.dbo.sysdatabases   
WHERE name NOT IN ('master','msdb','tempdb','model','distribution')   
ORDER BY 1  

OPEN DatabaseCursor  

FETCH NEXT FROM DatabaseCursor INTO @Database  
WHILE @@FETCH_STATUS = 0  
BEGIN  

   -- rebuild fulltext catalog
   set @cmd = 'DECLARE CatalogCursor CURSOR FOR 
        SELECT t.name AS TableName, c.name AS FTCatalogName, s.name as schemaname
        FROM ['+ @Database + '].sys.tables t JOIN ['+ @Database +'].sys.fulltext_indexes i
        ON t.object_id = i.object_id
        JOIN ['+ @Database + '].sys.fulltext_catalogs c
        ON i.fulltext_catalog_id = c.fulltext_catalog_id
        JOIN ['+ @Database + '].sys.schemas s ON t.schema_id = s.schema_id'
   --PRINT @cmd
   EXEC (@cmd)  


   OPEN CatalogCursor   

   FETCH NEXT FROM CatalogCursor INTO @Table, @Catalog, @Schema
   WHILE @@FETCH_STATUS = 0   
   BEGIN  

    SET @cmdB = 'USE ['+ @Database + ']; ALTER FULLTEXT CATALOG ' + @Catalog + ' REBUILD;'
    --PRINT @cmdB
    EXEC (@cmdB)


    FETCH NEXT FROM CatalogCursor INTO @Table, @Catalog, @Schema
   END   

   CLOSE CatalogCursor   


   OPEN CatalogCursor   

   FETCH NEXT FROM CatalogCursor INTO @Table, @Catalog, @Schema
   WHILE @@FETCH_STATUS = 0   
   BEGIN  

    SET @cmdC = 'USE ['+ @Database + ']; ALTER FULLTEXT INDEX ON ['+ @Database + '].[' + @Schema + '].[' + @Table + '] START FULL POPULATION;' 
    --PRINT @cmdC
    EXEC (@cmdC)

    FETCH NEXT FROM CatalogCursor INTO @Table, @Catalog, @Schema
   END   

   CLOSE CatalogCursor   
   DEALLOCATE CatalogCursor  



   FETCH NEXT FROM DatabaseCursor INTO @Database  
END  

CLOSE DatabaseCursor   
DEALLOCATE DatabaseCursor

END

У кого-нибудь есть метод, который не требует курсоров?


0

Обычно рекомендуется обновить полнотекстовый каталог с помощью триггеров. Это подход, который я использую в mssql, но в моем случае, поскольку у меня есть локализованное приложение с несколькими особыми требованиями, которые приводят меня к решению с использованием триггеров, эти решения работают на 100% начиная с двух лет назад.

Просмотрите вашу реализацию на этом примере .


Сейчас мои индексы настроены на автоматическое отслеживание изменений. Я читал, что изменение его на ручное и использование триггеров может на самом деле вызвать проблемы, когда один человек вставляет или обновляет запись в индексированной таблице до того, как еще не завершится триггерное обновление индекса из предыдущего обновления таблицы. Кажется, что автоматическое отслеживание изменений должно работать ... тем более, что в моих таблицах не так много записей.
Jargs

Я проверил мои настройки на примере ссылки, которую вы дали, но, похоже, все в порядке. Я даже пытался восстановить мою установку SQL Server, но проблема остается.
Jargs

1
Я не знаю, связано ли это, но у меня когда-то была проблема с заполнением полнотекстового каталога из-за проблем с Word Breaker. Если вы откроете SSMS и выберите «Хранилище» в своей базе данных, щелкните правой кнопкой мыши по полнотекстовому каталогу. Перейдите в Таблицы / Представления и посмотрите на Язык для Word Breaker. Есть ли колонки, которые используют разные языки для разбиения по словам? Я заметил, что если у вас есть разные языки для средств разбиения по словам в одной таблице, население не работает. Может быть, не связано, но кто знает?
Крейг Эфрейн

0

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

Для временного исправления я бы выполнил «Сканирование» (заполнение) таблицы, когда это произойдет.

http://msdn.microsoft.com/en-us/library/ms142575(v=sql.105).aspx

Используйте этот код:

ALTER FULLTEXT INDEX ON dbname.dbo.tablename
START FULL POPULATION;
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.