У меня возникло очень странное поведение, когда я выполняю запрос, использующий полнотекстовый индекс.
Моя база данных выглядит так (только важная часть для этой проблемы):
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.