Полнотекстовый запрос SQL Server к нескольким таблицам - почему так медленно? - PullRequest
7 голосов
/ 17 июня 2010

Я пытаюсь понять производительность строящегося полнотекстового запроса SQL Server 2008.

Следующий запрос, использующий полнотекстовый индекс, немедленно возвращает правильные результаты:

SELECT
    O.ID, O.Name
FROM
    dbo.EventOccurrence O
WHERE
    FREETEXT(O.Name, 'query')

т. Е. Все события EventOccurrence со словом «запрос» в их имени. И следующий запрос, использующий полнотекстовый индекс из другой таблицы, также сразу возвращает:

SELECT
    V.ID, V.Name
FROM
    dbo.Venue V
WHERE
    FREETEXT(V.Name, 'query')

т. все места со словом «запрос» в их названии. Но если я попытаюсь объединить таблицы и выполнить оба полнотекстовых запроса одновременно, вернется 12 секунд:

SELECT
    O.ID, O.Name
FROM
    dbo.EventOccurrence O
    INNER JOIN dbo.Event E ON O.EventID = E.ID
    INNER JOIN dbo.Venue V ON E.VenueID = V.ID
WHERE
    FREETEXT(E.Name, 'search')
    OR FREETEXT(V.Name, 'search')

Вот план выполнения: http://uploadpad.com/files/query.PNG

ОБНОВЛЕНИЕ: план в текстовом виде:

  |--Nested Loops(Left Semi Join, OUTER REFERENCES:([E].[ID], [V].[ID]))
       |--Hash Match(Inner Join, HASH:([E].[ID])=([O].[EventID]))
       |    |--Hash Match(Inner Join, HASH:([V].[ID])=([E].[VenueID]))
       |    |    |--Clustered Index Scan(OBJECT:([iScene].[dbo].[Venue].[PK_Venue] AS [V]))
       |    |    |--Clustered Index Scan(OBJECT:([iScene].[dbo].[Event].[PK_Event] AS [E]))
       |    |--Clustered Index Scan(OBJECT:([iScene].[dbo].[EventOccurrence].[PK_EventOccurrence] AS [O]))
       |--Concatenation
            |--Table-valued function
            |--Table-valued function

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

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

Может ли кто-нибудь объяснить (i), почему это так медленно, и (ii) если это даже поддерживается / если я даже правильно понимаю это.

Заранее спасибо за помощь.

Ответы [ 2 ]

11 голосов
/ 17 июня 2010

Попробуйте переписать запрос с помощью FREETEXTTABLE и посмотрите, поможет ли это.

SELECT
    O.ID, O.Name
FROM
    dbo.EventOccurrence O
    INNER JOIN dbo.Event E ON O.EventID = E.ID
    INNER JOIN dbo.Venue V ON E.VenueID = V.ID
    LEFT JOIN FREETEXTTABLE(dbo.Event, Name, 'search') EFT 
        ON E.ID = EFT.[KEY]
    LEFT JOIN FREETEXTTABLE(dbo.Venue, Name, 'search') VFT 
        ON V.ID = VFT.[KEY]
WHERE EFT.[KEY] IS NOT NULL OR VFT.[KEY] IS NOT NULL
1 голос
/ 17 июня 2010

Как сравнивается план выполнения для этого?

SELECT
    O.ID, O.Name
FROM
    dbo.EventOccurrence O
    WHERE O.EventID IN (
            SELECT
                E.ID
            FROM
                 dbo.Event E
            WHERE
                FREETEXT(E.Name, 'search')
            UNION
            SELECT
                E.ID
            FROM
                 dbo.Event E
                INNER JOIN dbo.Venue V ON E.VenueID = V.ID
            WHERE
                FREETEXT(V.Name, 'search')
                )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...