Full text search in SQL Server
-
- Уже с Приветом
- Posts: 2013
- Joined: 16 Mar 2002 10:01
- Location: New York City
Full text search in SQL Server
Есть такая задача. В базу данных поступает относительно большой поток информации. Он сколько не большой за одну транзакцию, сколько волнует количество таких транзакций. В секунду может запросто поступить 5 записей по 8К текста каждая. Может и больше..
Клиентское приложение может в любой момент составить такой запрос:
"Дайте мне последние 50 записей , которые содержат слово market".
Я натравил на таблицу, в которой сохраняются данные, Full Text Search feature.
тогда с учетом этой фичи, запрос будет выглядеть так
SELECT TOP 50 *
FROM Table
WHERE CONTAINS (*, 'market')
ORDER BY insert_time DESC
Проблема в том, что это будет работать только на те записи, которые были проиндексированы виндовым Index Service. У меня стоит full re-population этого каталога каждую полночь. Иными словами если этот запрос будет составлен в течение дня, то вернутся только записи только за вчера, потому что текущие записи которые поступают еще не проиндексированы.
Как обойти эту проблему? Делать full repopulation при вставке каждой записи будет очень дорого. Читал про change tracking и про incremental population но не понял до конца.
Какие могут быть выходы из положения?
Спасибо
Клиентское приложение может в любой момент составить такой запрос:
"Дайте мне последние 50 записей , которые содержат слово market".
Я натравил на таблицу, в которой сохраняются данные, Full Text Search feature.
тогда с учетом этой фичи, запрос будет выглядеть так
SELECT TOP 50 *
FROM Table
WHERE CONTAINS (*, 'market')
ORDER BY insert_time DESC
Проблема в том, что это будет работать только на те записи, которые были проиндексированы виндовым Index Service. У меня стоит full re-population этого каталога каждую полночь. Иными словами если этот запрос будет составлен в течение дня, то вернутся только записи только за вчера, потому что текущие записи которые поступают еще не проиндексированы.
Как обойти эту проблему? Делать full repopulation при вставке каждой записи будет очень дорого. Читал про change tracking и про incremental population но не понял до конца.
Какие могут быть выходы из положения?
Спасибо
-
- Уже с Приветом
- Posts: 2489
- Joined: 04 Feb 2002 10:01
- Location: Слава Україні!
Re: Full text search in SQL Server
Full population это накладно, кроме того, по ходу работы юзеров изменения не видны в поиске.
Я делаю так после того, как каталог создан:
exec sp_fulltext_catalog @catname, 'start_full'
exec sp_fulltext_table N'[dbo].[t1]', 'Start_change_tracking'
exec sp_fulltext_table N'[dbo].[t1]', 'Start_background_updateindex'
Я делаю так после того, как каталог создан:
exec sp_fulltext_catalog @catname, 'start_full'
exec sp_fulltext_table N'[dbo].[t1]', 'Start_change_tracking'
exec sp_fulltext_table N'[dbo].[t1]', 'Start_background_updateindex'
-
- Уже с Приветом
- Posts: 28294
- Joined: 29 Aug 2000 09:01
- Location: SPB --> Gloucester, MA, US --> SPB --> Paris
А вот такая идея
Все новые записи складировать в еще одну таблицу
Ночью запускать реиндексация а таблице делать truncate
При посике же делать full text search union all с результатом поиска по LIKE '%%' в этой таблице (по идее не очень большой).
Все новые записи складировать в еще одну таблицу
Ночью запускать реиндексация а таблице делать truncate
При посике же делать full text search union all с результатом поиска по LIKE '%%' в этой таблице (по идее не очень большой).
Зарегистрированный нацпредатель, удостоверение N 19719876044787 от 22.09.2014
-
- Уже с Приветом
- Posts: 2013
- Joined: 16 Mar 2002 10:01
- Location: New York City
давайте поподробнее расскажу как обстоят дела. Может я что не так делаю.
Есть таблица с четырьмя полями. первое поле - id (identity), второе - header (тип поля - text), третье - body (тип поля - text), четвертое - datetime (показывает когда была вставлена запись).
Информация приходит в виде header + body. Размер header небольшой, где то порядка 100 символов. Размер же body может достигать 8К. Вот эта информация вставляется в таблицу. В день вставляется порядка 8000 таких записей.
Поля header и body в таблице проиндексированы для Full Text Search (оба).
Информация в таблице хранится только за последние пять дней. Каждую ночь запускается job , который удаляет записи старые (оставляет только за последние пять дней). Следующая job - full population - следует сразу за этим. Происходит переиндексация. После этотго срабатывает третья job - database backup. Все...
Как я говорил выше стоит задача делать поиск по определенному слову в таблице в любой момент времени.
Можно поподробнее? В какие моменты делаете это? Через job делаете? Как часто?
я так понял, что алгоритм такой. Взять все строки из маленькой таблицы, вставить их в основную, проиндексировать основную таблицу заново, удалить строки из маленькой таблицы и начать складывать туда новые, так?
А как в job написать команду копирования строк из одной таблицы в другую?
Есть таблица с четырьмя полями. первое поле - id (identity), второе - header (тип поля - text), третье - body (тип поля - text), четвертое - datetime (показывает когда была вставлена запись).
Информация приходит в виде header + body. Размер header небольшой, где то порядка 100 символов. Размер же body может достигать 8К. Вот эта информация вставляется в таблицу. В день вставляется порядка 8000 таких записей.
Поля header и body в таблице проиндексированы для Full Text Search (оба).
Информация в таблице хранится только за последние пять дней. Каждую ночь запускается job , который удаляет записи старые (оставляет только за последние пять дней). Следующая job - full population - следует сразу за этим. Происходит переиндексация. После этотго срабатывает третья job - database backup. Все...
Как я говорил выше стоит задача делать поиск по определенному слову в таблице в любой момент времени.
exec sp_fulltext_catalog @catname, 'start_full'
exec sp_fulltext_table N'[dbo].[t1]', 'Start_change_tracking'
exec sp_fulltext_table N'[dbo].[t1]', 'Start_background_updateindex'
Можно поподробнее? В какие моменты делаете это? Через job делаете? Как часто?
Ночью запускать реиндексация а таблице делать truncate
я так понял, что алгоритм такой. Взять все строки из маленькой таблицы, вставить их в основную, проиндексировать основную таблицу заново, удалить строки из маленькой таблицы и начать складывать туда новые, так?
А как в job написать команду копирования строк из одной таблицы в другую?
-
- Уже с Приветом
- Posts: 1513
- Joined: 03 Apr 2001 09:01
- Location: London, UK
uniqueman wrote:Можно поподробнее? В какие моменты делаете это? Через job делаете? Как часто?
Зайдите в BooksOnLine и запустите поиск по change tracking and update index in background - документация, это вообще весьма полезная вещь. Вы, правда, не сказали какая у Вас версия SQL Server - приведенный Win32nipuh совет работает только в SQL2K.
-
- Уже с Приветом
- Posts: 2013
- Joined: 16 Mar 2002 10:01
- Location: New York City
chepackav wrote:uniqueman wrote:Можно поподробнее? В какие моменты делаете это? Через job делаете? Как часто?
Зайдите в BooksOnLine и запустите поиск по change tracking and update index in background - документация, это вообще весьма полезная вещь. Вы, правда, не сказали какая у Вас версия SQL Server - приведенный Win32nipuh совет работает только в SQL2K.
да, поставил то что написал Пух через Enterpise Manager. Действительно заработало. Все изменения отражаются в запросах. ВСе в реальном времени. Но вот памяти и проца жрет немеряно. Сейчас на машине стоит 512 метров. Думаю добавить еще столько же.
-
- Уже с Приветом
- Posts: 2013
- Joined: 16 Mar 2002 10:01
- Location: New York City
Вот такая проблема.
Мне надо найти в базе данных записи, которые содержат фразу допустим market closed. В соотвествии с мануалом пишу
SELECT *
FROM table
WHERE CONTAINS (8, ' "market closed" ')
То бишь внутри одиночных кавычек всю фразу заключаю в двойные кавычки.
Однако мне возвращаются также строки, в которых присутствует либо слово market либо closed либо фраза целиком
А мне нужно чтобы искалась только фраза целиком.
Что не так делаю?*
Спасибо
Мне надо найти в базе данных записи, которые содержат фразу допустим market closed. В соотвествии с мануалом пишу
SELECT *
FROM table
WHERE CONTAINS (8, ' "market closed" ')
То бишь внутри одиночных кавычек всю фразу заключаю в двойные кавычки.
Однако мне возвращаются также строки, в которых присутствует либо слово market либо closed либо фраза целиком
![HBZ :pain1:](./images/smilies/pain25.gif)
Что не так делаю?*
Спасибо
-
- Уже с Приветом
- Posts: 664
- Joined: 05 Jun 2002 01:11
uniqueman wrote:Вот такая проблема.
Мне надо найти в базе данных записи, которые содержат фразу допустим market closed. В соотвествии с мануалом пишу
SELECT *
FROM table
WHERE CONTAINS (8, ' "market closed" ')
То бишь внутри одиночных кавычек всю фразу заключаю в двойные кавычки.
Однако мне возвращаются также строки, в которых присутствует либо слово market либо closed либо фраза целикомА мне нужно чтобы искалась только фраза целиком.
Что не так делаю?*
Спасибо
This works for me:
Code: Select all
create table t1(id int identity, x varchar(100))
insert into t1(x) values('market closed')
insert into t1(x) values('closed')
insert into t1(x) values('market')
insert into t1(x) values('the day the market closed')
sp_fulltext_catalog 'test', 'create'
sp_fulltext_table 't1', 'create', 'test', 't1_idx'
sp_fulltext_column 't1', 'x', 'add'
sp_fulltext_table 't1', 'activate'
sp_fulltext_catalog 'test', 'start_full'
SELECT FulltextCatalogProperty ('test', 'PopulateStatus')
0
SELECT *
FROM t1
WHERE CONTAINS (x, ' "market closed" ')
1 market closed
4 the day the market closed
Rgds.
-
- Уже с Приветом
- Posts: 2013
- Joined: 16 Mar 2002 10:01
- Location: New York City
Что то не то. Текст в поле гораздо больше чем просто "market". Там 8К текста. И запрос возвращает запись, даже если встретилось слово "market" просто. Мне нужно именно "market closed" выражение чтобы было.
У меня стоит change tracking with background reindexing. Но я не думаю что это влияет.
ну спецы по SQL Server , где же вы когда необходимо. Тут вроде кто то даже занимался разработкой этого продукта. Что я не так делаю?
У меня стоит change tracking with background reindexing. Но я не думаю что это влияет.
ну спецы по SQL Server , где же вы когда необходимо. Тут вроде кто то даже занимался разработкой этого продукта. Что я не так делаю?
-
- Уже с Приветом
- Posts: 28294
- Joined: 29 Aug 2000 09:01
- Location: SPB --> Gloucester, MA, US --> SPB --> Paris
-
- Уже с Приветом
- Posts: 2013
- Joined: 16 Mar 2002 10:01
- Location: New York City
простите уважаемые, по моему это я напортачил.
У меня ночью происходит две задачи. Одна удаляет данные старые из таблицы, вторая делает full population. Так вот вторая задача выполнялась первее первой. ТО есть сначала делался population, а потом удалялись строки. Логически это неправильно я думаю. После удаления строк индексы будут указывать на нерпавильные данные.
Вообщем переставил местами задачи.
И еще. У меня на таблице стоит change tracking with background reindex. После того как сработает full population ночью, не надо ничего заново устанавливать в этом плане? change tracking так и будет продолжать работать?
У меня ночью происходит две задачи. Одна удаляет данные старые из таблицы, вторая делает full population. Так вот вторая задача выполнялась первее первой. ТО есть сначала делался population, а потом удалялись строки. Логически это неправильно я думаю. После удаления строк индексы будут указывать на нерпавильные данные.
Вообщем переставил местами задачи.
И еще. У меня на таблице стоит change tracking with background reindex. После того как сработает full population ночью, не надо ничего заново устанавливать в этом плане? change tracking так и будет продолжать работать?
-
- Уже с Приветом
- Posts: 5669
- Joined: 13 Oct 2000 09:01
- Location: East Bay, CA
-
- Уже с Приветом
- Posts: 2489
- Joined: 04 Feb 2002 10:01
- Location: Слава Україні!
FTS
То, что я написал выше делается один раз.
Например, я поставляю базу заказчику, в бэкапе.
Восстановил, создал каталог с нужным языком поиска, выполнил указанные выше утверждения, т.е.
1. full population,
2. changetracking
3. background
Заметьте, пункты 2 и 3 выполняются для каждого полноиндексируемого поля.
Все, больше НИЧЕГО по ходу работы делать не нужно.
Пункт 1 - выполняет начальную полную индексацию, без этого никуда,
2 и 3 - устанавливают признак, он даже остается, если база была завернута в бэкап с каталогом.
В этом случае, после ресторе Вам нужно сказать каталогу Rebuild, больше ничего.
Честно говоря, я не знаю зачем в этом случае ночью полный репопулэйт насильно делать? Ведь все отрабатывает "на лету".
Согласен с Dmitry67, в MS SQL полнотекстовый поиск/индексация сделаны так, что им есть еще над чем поработать.
Это может подтвердить и Alexandr Chepack, участвующий в этом форуме.
И еще: у меня на некоторых серверах при массированной всатвке/обновлении полнотекстовых полей сервер не всегда успевает индексировать, бывает, что он сам уходит в состояние инкрементальной доиндексации, но потом, когда нагрузка на него падает, он успевает дотянуть индексы. А ужесли он ночью сам работает - тогда и доиндексирует.
Job'ы я тоже для этого никакие не запускаю.
Ну и еще: такая нагрузка наблюдается у тех серверов, которые делают индексацию для языков, для которых нет списка шумных слов, и нет парсеров, знающих структуру языка, словоформы и т.д.
Каталоги в этом случае большие, и индексация идет медленнее, как пример, последний сервер с English+Arabic.
, Китайский язык отрабатывается очень неплохо.
Например, я поставляю базу заказчику, в бэкапе.
Восстановил, создал каталог с нужным языком поиска, выполнил указанные выше утверждения, т.е.
1. full population,
2. changetracking
3. background
Заметьте, пункты 2 и 3 выполняются для каждого полноиндексируемого поля.
Все, больше НИЧЕГО по ходу работы делать не нужно.
Пункт 1 - выполняет начальную полную индексацию, без этого никуда,
2 и 3 - устанавливают признак, он даже остается, если база была завернута в бэкап с каталогом.
В этом случае, после ресторе Вам нужно сказать каталогу Rebuild, больше ничего.
Честно говоря, я не знаю зачем в этом случае ночью полный репопулэйт насильно делать? Ведь все отрабатывает "на лету".
Согласен с Dmitry67, в MS SQL полнотекстовый поиск/индексация сделаны так, что им есть еще над чем поработать.
Это может подтвердить и Alexandr Chepack, участвующий в этом форуме.
И еще: у меня на некоторых серверах при массированной всатвке/обновлении полнотекстовых полей сервер не всегда успевает индексировать, бывает, что он сам уходит в состояние инкрементальной доиндексации, но потом, когда нагрузка на него падает, он успевает дотянуть индексы. А ужесли он ночью сам работает - тогда и доиндексирует.
Job'ы я тоже для этого никакие не запускаю.
Ну и еще: такая нагрузка наблюдается у тех серверов, которые делают индексацию для языков, для которых нет списка шумных слов, и нет парсеров, знающих структуру языка, словоформы и т.д.
Каталоги в этом случае большие, и индексация идет медленнее, как пример, последний сервер с English+Arabic.
![Smile :-)](./images/smilies/icon_smile.gif)
-
- Уже с Приветом
- Posts: 2013
- Joined: 16 Mar 2002 10:01
- Location: New York City
Re: FTS
Честно говоря, я не знаю зачем в этом случае ночью полный репопулэйт насильно делать? Ведь все отрабатывает "на лету".
у меня каждую ночь удаляются некотороые записи из таблицы. Я храню данные только за последние пять дней. Мне показалось, что после удаления записей из таблицы надо сделать заново full population, чтобы переиндексировать заново все записи. Разве это делать не нужно?
-
- Уже с Приветом
- Posts: 2013
- Joined: 16 Mar 2002 10:01
- Location: New York City
хм. проблема до сих пор существует. При попытке найти что то подобное "market closed", выдаются как правильные результаты, так и записи, не имеющие такой пары слов.
Может ли это быть из за того, что ночью я удаляю некоторые записи а потом делаю full population? У меня на таблице стоит change tracking with backgroung reindex. Нужно ли делать все равно полную population после удаления записей?
Может ли это быть из за того, что ночью я удаляю некоторые записи а потом делаю full population? У меня на таблице стоит change tracking with backgroung reindex. Нужно ли делать все равно полную population после удаления записей?