То, как добавить больше, ИЛИ поиски с СОДЕРЖИТ, Приносит Запрос для Проверки?

У меня есть простой запрос, который полагается на две полнотекстовых индексированных таблицы, но он работает чрезвычайно медленный, когда мне объединили СОДЕРЖАНИЕ с любым дополнительным ИЛИ поисковым. Как замечено в плане выполнения, эти два полнотекстовых поиска сокрушают производительность. Если я запрашиваю со всего 1 из СОДЕРЖАНИЯ, или ни один, запрос является подвторым, но момент, который Вы добавляете ИЛИ в соединение, запрос становится злополучным.

Эти две таблицы являются ничем специальным, они не чрезмерно широки (42 седла в один, 21 в другом; возможно, 10 седлами является FT, индексированный в каждом), или даже содержите очень много записей (36k, обращает внимание в самом большом из двух).

Я смог решить производительность путем разделения этих двух, СОДЕРЖИТ поиски в их собственные Запросы Select и затем ОБЪЕДИНЕНИЕ три вместе. Является это обходное решение ОБЪЕДИНЕНИЯ моей единственной надеждой?

SELECT     a.CollectionID
FROM       collections    a
INNER JOIN determinations b ON a.CollectionID = b.CollectionID 
WHERE      a.CollrTeam_Text LIKE '%fa%'
           OR CONTAINS(a.*, '"*fa*"')
           OR CONTAINS(b.*, '"*fa*"')

План выполнения:

execution plan

10
задан double-beep 11 June 2019 в 17:08
поделиться

4 ответа

Мне было бы любопытно посмотреть, будет ли LEFT JOIN к эквивалентному CONTAINSTABLE работать лучше. Что-то вроде:

SELECT     a.CollectionID
FROM       collections    a
INNER JOIN determinations b ON a.CollectionID = b.CollectionID 
LEFT JOIN CONTAINSTABLE(a, *, '"*fa*"') ct1 on a.CollectionID = ct1.[Key]
LEFT JOIN CONTAINSTABLE(b, *, '"*fa*"') ct2 on b.CollectionID = ct2.[Key]
WHERE      a.CollrTeam_Text LIKE '%fa%'
           OR ct1.[Key] IS NOT NULL
           OR ct2.[Key] IS NOT NULL
6
ответ дан 4 December 2019 в 01:29
поделиться

Я собирался предложить UNION каждый в качестве отдельного запроса, но когда я прочитал ваш вопрос, я увидел, что вы это нашли. Я не могу придумать лучшего способа, так что если это поможет, используйте его. Метод UNION - это распространенный подход к неэффективному запросу, который имеет несколько условий OR, каждое из которых хорошо работает само по себе.

3
ответ дан 4 December 2019 в 01:29
поделиться

Мы столкнулись с точно такой же проблемой и в то время объяснили это тем, что наш запрос был плохо сформирован - мол, SQL 2005 позволил нам избежать этого, а 2008 - нет.

В итоге мы разделили запрос на 2 SELECT, которые вызывались с помощью IF. Рад, что кто-то еще столкнулся с такой же проблемой и что это известная проблема. Мы наблюдали, как запросы к таблице с ~150 000 строк + полный текст выполнялись от < 1 секунды (2005) до 30+ секунд (2008).

0
ответ дан 4 December 2019 в 01:29
поделиться

Я бы, наверное, использовал UNION. Если вы действительно против, вы можете попробовать что-нибудь вроде:

SELECT a.CollectionID
FROM collections a
  LEFT OUTER JOIN (SELECT CollectionID FROM collections WHERE CONTAINS(*, '"*fa*"')) c
    ON c.CollectionID = a.CollectionID
  LEFT OUTER JOIN (SELECT CollectionID FROM determinations WHERE CONTAINS(*, '"*fa*"')) d
    ON d.CollectionID = a.CollectionID
WHERE a.CollrTeam_Text LIKE '%fa%'
   OR c.CollectionID IS NOT NULL
   OR d.CollectionID IS NOT NULL
1
ответ дан 4 December 2019 в 01:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: