Производительность полнотекстового поиска SQL Server значительно снижается при использовании «ИЛИ» в предложении where - PullRequest
0 голосов
/ 04 ноября 2010

Предположим, у меня есть две таблицы tab1, tab2. Полнотекстовые индексы, созданные во всех столбцах varchar в этих двух таблицах. Затем выполните следующий SQL:

SELECT *  
  FROM tab1 a 
  JOIN tab2 b on a.ID = b.ID
 WHERE CONTAINS(a.*, @keystring) 
    OR CONTAINS(b.*,@keystring)

Это довольно медленно (почти 30 секунд). Но если я выдаю следующий SQL:

SELECT * 
  FROM tab1 a 
  JOIN tab2 b on a.ID = b.ID
 WHERE CONTAINS(a.*, @keystring) 

... или:

SELECT *  
  FROM tab1 a 
  JOIN tab2 b on a.ID = b.ID
 WHERE CONTAINS(b.*,@keystring)

Производительность довольно хорошая (меньше секунды)

Как решить эту проблему?

Ответы [ 2 ]

2 голосов
/ 04 ноября 2010

вы пробовали:

SELECT *  
  FROM tab1 a  
  JOIN tab2 b on a.ID = b.ID 
 WHERE CONTAINS(a.*, @keystring)  
UNION 
SELECT *   
  FROM tab1 a  
  JOIN tab2 b on a.ID = b.ID 
 WHERE CONTAINS(b.*,@keystring) 

Или используйте UNION all, если вам все равно, есть ли дубликаты, где строка ключей - это обе таблицы.

Посмотрите на свои планы выполнения, чтобы увидеть разницу, но ИЛИ часто делает запрос намного медленнее.

1 голос
/ 04 ноября 2010

Реальная проблема заключается в том, что при наличии «ИЛИ» правильный индекс не может быть выбран, так как «правильный» индекс будет зависеть от результата первой оценки для каждой отдельной строки.Поэтому СУБД выбирает один индекс (скорее всего, правильный для первой части «ИЛИ») и, в случае, если первая оценка возвращается как «ложная», запускает второй неиндексированный.Это делает это медленно.Производительность для этого сильно зависит от того, как часто первые оценки возвращаются как «ложные».

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