Как вы выполняете полный текстовый поиск нескольких критериев на левых таблицах в SQL Server?

StackOverflow https://stackoverflow.com/questions/35954

  •  09-06-2019
  •  | 
  •  

Вопрос

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

select c.Id, c.Name, c.CountryCode, c.CustomerNumber, cacc.AccountNumber, ca.Line1, ca.CityName, ca.PostalCode
from dbo.Customer as c
left join dbo.CustomerAddress as ca on ca.CustomerId = c.Id
left join dbo.CustomerAccount as cacc on cacc.CustomerId = c.Id
where  c.CountryCode = 'XX' and (cacc.AccountNumber like '%C17%' or c.Name like '%op%'       
or ca.Line1 like '%ae%' or ca.CityName like '%ab%' or ca.PostalCode like '%10%')

В базе данных с 90 000 записей этот запрос занимает около 7 секунд (очевидно, все соединения и лайки облагаются налогом).

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

Есть ли способ сделать это в полнотекстовом поиске?


@Дэйвид

Да, есть индексы на идентификаторах.

Я попытался добавить индексы в материалах CustomerAddress (CityName, PostalCode и т. Д.), И это сократило запрос до 3 секунд, но я все еще нахожу это слишком медленным для чего -то подобного.

Обратите внимание, что все текстовые поля (за исключением идентификаторов) являются nvarchars, а Line1 является NVARCHAR 1000, так что это может повлиять на скорость, но все же.

Это было полезно?

Решение

Запустите его через анализатор запросов и посмотрите, что такое план запроса. Я предполагаю, что поиск двойного корня (т. Е. %AE %) приводит к тому, что он выполняет сканирование таблицы при поиске подходящих рядов. Двойной корневой поиск по своей природе медленные, так как вы не можете использовать какой -либо индекс, чтобы соответствовать их обычно.

Другие советы

Примечание: это на самом деле не ответ, просто попытка прояснить, что на самом деле может вызвать проблемы (ы).

90 000 записей - это действительно небольшой набор данных, и запрос относительно прост с двумя соединениями. У вас есть индексы на CustomerAddress.customerid и CustomerAccount.customerid? Это, кажется, более вероятно, что вызывает проблемы с производительностью, чем условие, как предикаты. Вы обычно ищете, чтобы найти совпадение на всех этих столбцах одновременно?

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

Одна быстрая проверка была бы во времени только той части запроса, включающего текстовый поиск. Что-то вроде этого:

SELECT  ca.Line1, ca.CityName, ca.PostalCode
FROM    CustomerAddress as ca
WHERE   ca.CustomerId = <some id number>
AND     (ca.Line1 LIKE '%ae%' OR ca.CityName LIKE '%ab%' OR ca.PostalCode LIKE '%10%');

Если это займет много времени, то LIKES является проблемой (удаляйте одно выражение за раз из ORED Line, чтобы увидеть, вызывает ли только один из этих столбцов замедление). Если это быстро, то соединения подозрительны.

Вы также можете написать аналогичный запрос для таблицы CustomerAccount.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top