Вы можете прочитать предысторию, если хотите, после изменения моего некластеризованного индекса на кластеризованный индекс, вещи начали работать намного быстрее.Проблема с первоначальным планом запроса, занимающим 2-3 секунды, все еще остается.Тем не менее, подсказка запроса плана хранения немного улучшилась.
BACKSTORY
У меня есть инвертированный индекс, в котором я храню вещи, которые хочу найти в простой реализации поиска (хотя ничего простого нето поиске).
Когда я ввожу запрос, подобный этому "ma br", он создаст этот SQL
SELECT EntityType, EntityID FROM InvertedIndex WHERE Term LIKE @p0
INTERSECT
SELECT EntityType, EntityID FROM InvertedIndex WHERE Term LIKE @p1
--@p0 String --'ma%'
--@p1 String --'br%'
Для каждого поискового запроса есть еще INTERSECT
и SELECT
И по большей части это работает очень хорошо.Я правильно проиндексировал столбец Term
и проверил планы выполнения на возможные узкие места.Прямо сейчас индекс содержит около 150000 строк, и поиск происходит мгновенно, как и ожидалось.
Что немного раздражает, так это то, что обычно выполнение первого запроса определенного ранга занимает намного больше времени.Бьюсь об заклад, это потому, что оптимизатор запросов переоценивает план выполнения.Но как мне быть с этим?Чем больше запросов я запускаю к серверу, тем меньше он останавливается, но каждый другой запрос длится примерно 2-3 секунды.Это не имеет большого значения, но иногда это намного дольше, и я просто не вижу, откуда это происходит и как с этим бороться.Это должно быть молниеносно.
РЕДАКТИРОВАТЬ
Схема выглядит следующим образом:
CREATE TABLE InvertedIndex (
Term varchar(255) NOT NULL,
Ordinal tinyint NOT NULL,
EntityType tinyint NOT NULL,
EntityID int NOT NULL
)
Два индекса:
CREATE NONCLUSTERED INDEX IX_InvertedIndex ON InvertedIndex (Term)
INCLUDE (Ordinal, EntityType, EntityID)
CREATE NONCLUSTERED INDEX IX_InvertedIndex_Reverse ON InvertedIndex (EntityType, EntityID)
Этот материал остается, что происходит, когда операции вставки и удаления выполняются, когда индекс (InvertedIndex) должен быть обновлен и когда-либо полностью перестроен, повлияет ли это на использование QUERY PLAN?
Вот пример завершенного запроса, который действительно очень медленный., 3-5 секунд, и я не могу понять, почему ... Предложение ORDER BY
предназначено для того, чтобы дать словам, которые соответствуют определенной позиции, более высокий порядок сортировки (появляются первыми в наборе результатов), однако это стало экспоненциально медленнее для каждогопоисковый термин.
WITH Search AS (
SELECT EntityType, EntityID FROM InvertedIndex WHERE Term LIKE @p0
INTERSECT
SELECT EntityType, EntityID FROM InvertedIndex WHERE Term LIKE @p1
INTERSECT
SELECT EntityType, EntityID FROM InvertedIndex WHERE Term LIKE @p2
)
SELECT p.PersonID
, p.FullName
, p.Email
, p.MobilePhone
, p.HomeAddress
, p.HomeCity
FROM Search AS s
INNER JOIN Person AS p ON p.PersonID = s.EntityID AND s.EntityType = @pPersonEntityType
ORDER BY (CASE WHEN @p3 IN (SELECT Ordinal FROM InvertedIndex WHERE Term LIKE @p0 AND EntityID = s.EntityID AND EntityType = s.EntityType) THEN 0 ELSE 1 END) + (CASE WHEN @p4 IN (SELECT Ordinal FROM InvertedIndex WHERE Term LIKE @p1 AND EntityID = s.EntityID AND EntityType = s.EntityType) THEN 0 ELSE 1 END) + (CASE WHEN @p5 IN (SELECT Ordinal FROM InvertedIndex WHERE Term LIKE @p2 AND EntityID = s.EntityID AND EntityType = s.EntityType) THEN 0 ELSE 1 END)
@p0 String --'ma%'
@p1 String --'br%'
@p2 String --'mi%'
@p3 Int32 --1
@p4 Int32 --2
@p5 Int32 --3
Смысл вышеприведенного запроса заключается в поиске всех терминов в InvertedIndex
, а затем для каждого поискового термина есть пересечение, это логическое соединение, которое я хочу использовать дляограничить поиск.Порядковый номер представляет исходную позицию слова, когда оно было проиндексировано.Каждая запись в InvertedIndex представляет кортеж, и если поисковый термин соответствует некоторому элементу этого N-кортежа, он считается лучшим.Вот почему мне нужно сделать этот интересный заказ с помощью подзапросов.Но это действительно медленно.
ОТВЕТ
Если я изменяю IX_InvertedIndex
на кластеризованный индекс, это на порядок увеличивает скорость запроса (хотя я не знаю почему):
CREATE CLUSTERED INDEX IX_InvertedIndex ON InvertedIndex (Term)