1

Wir versuchen, Volltextsuche auf Azure-Datenbank zu verwenden und Leistungsprobleme bei der Verwendung von CONTAINS-Suche.Volltextsuche mit CONTAINS ist sehr langsam

Unsere Daten haben Sternschema, Fact-Tabelle hat Cluster-Spaltenspeicher-Index aktiviert und rund 40 Millionen Zeilen. Unten ist, wie wir ENTHALTEN auf Dimension verwenden und auf verschiedene Abfragen auf Faktentabelle keine Aggregation:

Abfrage 1 mit VORHANDEN:

SELECT f.[FK_DimCompanyCodeId], SUM(f.NetValueInUSD) 
FROM [SPENDBY].[FactInvoiceDetail] f 

WHERE EXISTS (
     SELECT * FROM [SPENDBY].[DimCompanyCode] d 

     WHERE f.[FK_DimCompanyCodeId] = d.Id 
     AND CONTAINS(d.*, 'Comcast')) 

GROUP BY f.[FK_DimCompanyCodeId] 

ORDER BY SUM(f.NetValueInUSD) DESC 

Diese Abfrage für immer laufen scheint und nie das Ergebnis zurück.

Es ist nicht gruppierten Index für den Fremdschlüssel FK_DimCompanyCodeId] und es gibt nur eine Zeile zurückgegeben bei der Suche Comcast:

SELECT id FROM [SPENDBY].[DimCompanyCode] d 
WHERE CONTAINS(d.*, 'Comcast'); 
-- will return id = 5 

Und es gibt rund 27 Millionen Zeilen von Faktentabelle, die FK_DimCompanyCodeId = 5 hat.

Abfrage 2 INNER JOIN mit:

SELECT f.[FK_DimCompanyCodeId], SUM(f.NetValueInUSD) 
FROM [SPENDBY].[FactInvoiceDetail] f 

INNER JOIN [SPENDBY].[DimCompanyCode] d ON (f.[FK_DimCompanyCodeId] = d.Id) 
WHERE CONTAINS(d.*, 'Comcast') 

GROUP BY f.[FK_DimCompanyCodeId] 
ORDER BY SUM(f.NetValueInUSD) DESC 

Diese Abfrage für immer laufen scheint und nie so gut das Ergebnis zurück.

Abfrage 3 mit #temp Tabelle:

SELECT id INTO #temp FROM [SPENDBY].[DimCompanyCode] d 
WHERE CONTAINS(d.*, 'Comcast'); 

SELECT f.[FK_DimCompanyCodeId], SUM(f.NetValueInUSD) 
FROM [SPENDBY].[FactInvoiceDetail] f 

WHERE EXISTS (
     SELECT * FROM #temp 
     WHERE f.[FK_DimCompanyCodeId] = #temp.Id) 

GROUP BY f.[FK_DimCompanyCodeId] 

ORDER BY SUM(f.NetValueInUSD) DESC 

Sehr schnell, gibt das Ergebnis nach 5 Sekunden.

Warum Volltextsuche für den Fall so langsam ist 1 und Fall 2.

+0

gefunden ähnliche Frage: https://stackoverflow.com/questions/2750870/sql-serve-full-text-search-with-containstable-is-very-slow-when-used-in-join –

+0

Können Sie Pläne für die tatsächliche Ausführung hinzufügen (das x ml) von Ihren Fragen? Das wäre wirklich nützlich. – wBob

Antwort

0

Schließlich dachte ich CONTAINS funktioniert gut auf bestimmte Spalte aus (Description zum Beispiel):

SELECT f.[FK_DimCompanyCodeId], SUM(f.NetValueInUSD) 
FROM [SPENDBY].[FactInvoiceDetail] f 
WHERE f.[FK_DimCompanyCodeId] IN (
     SELECT d.Id FROM [SPENDBY].[DimCompanyCode] d 
     WHERE CONTAINS(d.[Description], 'Comcast') 
) 
GROUP BY f.[FK_DimCompanyCodeId] 
ORDER BY SUM(f.NetValueInUSD) DESC 

Um für die gesamte Tabelle zu suchen, CONTAINSTABLE die beste Leistung haben und vermeiden Tabelle mit #temp:

SELECT f.[FK_DimCompanyCodeId], SUM(f.NetValueInUSD) 
FROM [SPENDBY].[FactInvoiceDetail] f 
LEFT OUTER JOIN CONTAINSTABLE([SPENDBY].[DimCompanyCode], *, '"Comcast"') ct 
ON f.[FK_DimCompanyCodeId] = ct.[Key] 
WHERE ct.[Key] IS NOT NULL 
GROUP BY f.[FK_DimCompanyCodeId] 
ORDER BY SUM(f.NetValueInUSD) DESC 
1

Das Problem Indizes im Wettbewerb - ein für die JOIN und einen für die Filter. Vielleicht wäre eine Unterabfrage SQL Server überzeugen zuerst den Textindex zu verwenden:

SELECT f.[FK_DimCompanyCodeId], SUM(f.NetValueInUSD) 
FROM [SPENDBY].[FactInvoiceDetail] f JOIN 
    (SELECT id 
     FROM [SPENDBY].[DimCompanyCode] cc 
     WHERE CONTAINS(cc.*, 'Comcast') 
    ) cc 
    ON cc.id = f.FK_DimCompanyCodeId 
GROUP BY f.[FK_DimCompanyCodeId] 
ORDER BY SUM(f.NetValueInUSD) DESC 

Es wäre wahrscheinlich auch helfen, wenn Sie auf FactInvoiceDetail(FK_DimCompanyCodeId) einen Index haben.

+0

Vielen Dank für Ihre Antwort, ich habe versucht, Ihre Abfrage auszuführen und es scheint, das Ergebnis nie wieder –

+0

Hi Cuong - können Sie die geschätzten Pläne für die Beispiele, die auf unbestimmte Zeit lief - und dann der eigentliche Plan für die schnelle Ausführung? –

+0

@JoeSack: Bitte werfen Sie einen Blick auf meine Antwort, ich fand heraus, dass 'CONTAINSTABLE' die beste Leistung erzielt –