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'得到最好的性能 –

相关问题