1

我們嘗試使用Azure上的數據庫,全文搜索,得到了使用CONTAINS搜索性能問題。有包含完整的文本搜索是很慢的

我們的數據有星型模式,事實表已經啓用聚集列存儲索引和大約40萬行。下面是我們如何使用包含維和活動等不同的查詢事實表的聚合:使用

查詢1 EXISTS:

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 

該查詢似乎永遠運行下去,永不返回結果。

有外鍵FK_DimCompanyCodeId]非聚集索引,並且只有一個返回搜索Comcast當行:

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

而且還有約27萬行具有FK_DimCompanyCodeId = 5事實表。

查詢2使用INNER JOIN:

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 

該查詢似乎永遠再也不返回結果爲好。使用

查詢3 #temp表:

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 

非常快,返回5秒後的結果。

爲什麼全文搜索是在例1和例2

+0

中的相關問題:https://stackoverflow.com/questions/2750870/sql-serve-full-text-search-with-containstable-is-very-slow-when-used-in-join –

+0

您是否可以添加實際執行計劃(x毫升)從您的查詢?這將是真正有用的。 – wBob

回答

0

最後,我想通了CONTAINS非常適用於(例如Description)特定列:

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 

爲了搜索整個表格,CONTAINSTABLE將擁有最好的性能和避免使用#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

問題是競爭指標如此之慢 - 一個爲JOIN,一個用於過濾器。也許一個子查詢會說服SQL Server以首先使用文本索引:

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 

它可能還可以幫助,如果你有FactInvoiceDetail(FK_DimCompanyCodeId)的索引。

+0

感謝您的回答,我試圖運行查詢,似乎結果不會返回以及 –

+0

的Cuong嗨 - 你可以分享估計計劃是無限期跑例子 - 然後在快速執行的實際計劃? –

+0

@JoeSack:請看看我的回答,我發現使用'CONTAINSTABLE'得到最好的性能 –

相關問題