TSQL Query с полнотекстовым поиском не останавливается - PullRequest
0 голосов
/ 03 сентября 2018

У меня возникло очень странное поведение, когда я выполняю запрос, использующий полнотекстовый индекс.

Моя база данных выглядит так (только важная часть для этой проблемы):

table Catalogs 
(
     Id int primary key not null, ...
)

table Products 
(
    Id int primary key not null, 
    CatalogId int not null foreign key references Catalogs(Id), ...
)

table FulltextData 
(
    ProductId int not null, 
    Name nvarchar(100), 
    Description nvarchar(max), 
    Keywords nvarchar(max), 
    Timestamp timestamp not null,

    constraint PK_FulltextData primary key (ProductId)
)

Каталог содержит несколько товаров (в настоящее время до 500.000), которые, конечно, имеют несколько полей, таких как name, description, price. Таблица Products является большой (> 40 миллионов записей).

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

create fulltext catalog ProductsFTC

и после этого я создал полнотекстовый индекс, подобный этому

create fulltext index on FulltextData(Name,Description,Keywords) 
key index PK_FulltextData on ProductsFTC 
with(stoplist=off,change_tracking=manual)

После того, как каталог (со всеми данными о продукте) был импортирован в базу данных, я выполняю добавочную совокупность с помощью следующего оператора:

ALTER FULLTEXT INDEX ON FulltextData START INCREMENTAL POPULATION

После этого я проверяю следующее утверждение, готов ли полнотекстовый индекс:

SELECT FULLTEXTCATALOGPROPERTY('ProductsFTC', 'PopulateStatus')

Пока все хорошо. И вот идет та часть, которая не имеет смысла для меня.

Когда я выполняю полнотекстовый поиск в новом импортированном каталоге (после обновления полнотекстового индекса), генерируются два запроса:

Первый запрос подсчитывает количество товаров, которое содержит слово с префиксом book :

select count(*) 
from Products p 
inner join FulltextData f on p.Id = f.ProductId
where p.CatalogId = 4711 
  and contains((name, description, keywords), '"book*"')

Мне нужно посчитать результаты, потому что пользователь хочет видеть эту информацию: products 50 to 100 of 41.000 (пожалуйста, не спрашивайте, почему).

Второй запрос возвращает только 50 товаров, которые пользователь может проверить:

select Id, Name, Description, Keywords, Spn, Price
from Products p 
inner join FulltextData f on p.Id = f.ProductId
where CatalogId = 4711 
  and contains((name, description, keywords), '"book*"')
order by Spn 
    offset 50 rows fetch next 50 rows only

Первый запрос (...count(*)...) - это запрос, который не останавливается. Сначала я подумала, может быть, в полнотекстовом индексе слишком много записей. Но когда я немного изменяю первый запрос (вместо CatalogId=4711 я использую CatalogId in (42,4711)), я получаю мгновенные результаты!

Поиск только по каталогу 4711 не остановит выполнение.

Поиск по каталогу 4711 и 42 совершенно в порядке и дает мне мгновенные результаты.

И когда я выполняю поиск только в каталоге 42 , я также получаю мгновенный результат (= 0).

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

Чего мне не хватает? Любая помощь будет отличной!

Я использую SQL Server 2016 (13.0.4001.0), но база данных должна быть совместима с SQL Server 2014.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...