Переиндексирование большой базы данных SQL Server в Lucene - PullRequest
1 голос
/ 24 февраля 2011

У нас есть метод веб-сервиса, который принимает некоторые данные и помещает их в индекс Lucene. Мы используем его для индексирования новых и обновленных записей из нашего веб-приложения asp.net.

Эти записи хранятся в большой таблице SQL Server (20M строк и растут), и мне нужен способ переиндексировать всю таблицу в случае, если текущий индекс будет удален или поврежден. Я не уверен, каков оптимальный способ извлечения фрагментов данных из большой таблицы. В настоящее время мы используем тот факт, что таблица имеет автоинкремент PK, поэтому мы получаем куски по 1000 строк, пока она не начнет ничего не возвращать. Вроде как (на псевдо языке):

i = 0
while (true)
{
    SELECT col1, col2, col3 FROM mytable WHERE pk between i and i + 1000
    .... if result is empty 20 times in a row, break ....
    .... otherwise send result to web service to reindex ....
    i = i + 1000
}

Таким образом, нам не нужно ВЫБРАТЬ СЧЕТЧИК (*), который может сильно снизить производительность, и мы просто увеличиваем значения pk, пока не перестанем получать какие-либо результаты. Это имеет свои недостатки: если где-то в таблице будет дыра, превышающая 20 000 значений, она прекратит индексирование, предполагая, что оно достигло конца, но это компромисс, который мы должны пережить сейчас.

Кто-нибудь может предложить более эффективный способ получения данных из таблицы для индексации? Я предполагаю, что мы не первые, кто сталкивается с этой проблемой - в настоящее время широко используются поисковые системы:)

Ответы [ 3 ]

1 голос
/ 25 февраля 2011

Для того, что мы делаем с Lucene, нам редко нужно переиндексировать все .Я не могу вспомнить ни одного случая, когда бы весь индекс был поврежден (Lucene на самом деле вполне безопасен / хорош в этом), но было много раз, когда отдельные элементы нужно было переиндексировать по той или иной причине.Я бы сказал, что наиболее часто встречающиеся шаблоны переиндексации были бы:

  • элементы переиндексации по заданному идентификатору (или набору идентификаторов)
  • элементы переиндексации по заданному периоду времени

Последнее, конечно, требует отдельного индекса дБ для соответствующих полей даты, что должно быть немного дорого для записей более 20M, но мы решили пойти на это (наше самое большое развертывание имело до 10 миллионов записей) как дискВ любом случае, в наши дни пространство дешевое.

РЕДАКТИРОВАТЬ: добавлено несколько объяснений в соответствии с комментариями автора вопроса.

Если структура исходных данных изменяется, что требует переиндексации всех записей, наш подход заключается в развертывании новыхкод, который гарантирует, что все новые данные верны (в основном формирует правильный Lucene Document с этого момента).Затем, после того, как мы можем переиндексировать вещи партиями (вручную или вручную), предоставив соответствующие диапазоны периодов.Это в определенной степени относится и к изменениям версии Lucene.

0 голосов
/ 24 февраля 2011

На самом деле я только что понял - я могу использовать IDENT_CURRENT (имя_таблицы), чтобы получить последний сгенерированный идентификатор, и использовать его вместо MAX () или Count () - этот метод должен уничтожить два других:)

0 голосов
/ 24 февраля 2011

Почему COUNT (*) - убийца производительности? Что насчет MAX (id)? Я думаю, что индекс предоставит информацию, необходимую для этих запросов. У вас есть индекс первичного ключа, верно?

...