2010-06-17 3 views
6

Ich versuche, die Leistung einer SQL Server 2008-Volltextabfrage zu verstehen, die ich erstelle.SQL Server-Volltextabfrage über mehrere Tabellen - warum so langsam?

Die folgende Abfrage, einen Volltextindex verwendet wird, gibt die richtigen Ergebnisse sofort:

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

dh alle EventOccurrences mit dem Wort ‚Abfrage‘ in ihrem Namen. Und die folgende Abfrage, die einen Volltextindex aus einer anderen Tabelle verwendet, wird ebenfalls sofort zurückgegeben:

ie. alle Orte mit dem Wort "query" in ihrem Namen. Aber wenn ich versuche, die Tabellen zu verknüpfen und tun, beiden Volltextabfragen auf einmal, es 12 Sekunden zurück:

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') 

Hier ist der Ausführungsplan: http://uploadpad.com/files/query.PNG

UPDATE: der Plan in Text Form:

|--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 

Aus meiner Lektüre, ich habe es nicht einmal möglich war, eine freie Textabfrage über mehrere Tabellen in dieser Art und Weise zu machen, also bin ich nicht sicher, ob ich das richtig bin zu verstehen.

Beachten Sie, dass, wenn ich die WHERE-Klausel aus dieser letzten Abfrage entfernen, es alle Ergebnisse innerhalb einer Sekunde zurückgibt, so ist es definitiv der Volltext, der das Problem hier verursacht.

Kann jemand erklären (i) warum das so langsam ist und (ii) ob das überhaupt unterstützt wird/wenn ich das überhaupt richtig verstehe.

Vielen Dank im Voraus für Ihre Hilfe.

+0

Können Sie den tatsächlichen Plan veröffentlichen. Nicht das Bild? –

+0

OK habe es nur für dich hinzugefügt. –

Antwort

11

Versuchen Sie, Ihre Abfrage mit FREETEXTTABLE neu zu schreiben und sehen, ob das hilft.

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

Wie vergleicht der Ausführungsplan für diesen?

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') 
       ) 
+0

Ah, Akademiker jetzt sowieso! –

+0

Danke für diese Antwort ... das war etwas anderes, das auch versucht hat, aber es scheint irgendwie unordentlich zu sein, zumal meine eigentliche Abfrage viel komplexer ist als die abgespeckte Version, die ich oben gepostet habe. –