1

Azure 데이터베이스에서 전체 텍스트 검색을 사용하려고하고 CONTAINS 검색 사용시 성능 문제가 발생합니다.CONTAINS가 포함 된 전체 텍스트 검색이 매우 느림

데이터에는 스타 스키마가 있으며 팩트 테이블에는 클러스터 된 컬럼 스토어 색인이 있고 약 4 천만 개의 행이 있습니다.

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 

이 쿼리 영원히 실행 보인다 및 결과를 반환하지 : 사용

쿼리 1이 존재 : 우리가 차원에 CONTAINS 사용하고 다른 질의에 사실 테이블에 응집 어떻게 아래입니다.

비 클러스터형 인덱스는 외래 키 FK_DimCompanyCodeId]에 있습니다 및 Comcast 검색 반환 단 하나의 행이 :

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

가 그리고 FK_DimCompanyCodeId = 5을 가지고 사실 테이블의 약 2700 만 행이. INNER를 사용하여

쿼리 2는 가입 :이 쿼리 영원히 결코 실행 보인다

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 ml)를 귀하의 검색어에서? 그것은 진정으로 유용 할 것입니다. – 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를 설득 것입니다 : 당신이 FactInvoiceDetail(FK_DimCompanyCodeId)에 인덱스가 있다면 그것은 아마도 도움이 될

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 

.

+0

귀하의 답변을 주셔서 감사합니다, 나는 귀하의 쿼리를 실행했는데 결과도 결코 반환하지 않는 것 같습니다 –

+0

안녕하세요 쿠옹 - 당신은 무한히 실행되는 예제에 대한 견적을 공유 할 수 있습니까 - 그리고 빠른 실행을위한 실제 계획? –

+0

@JoeSack : 내 대답을 한 번보세요. 'CONTAINSTABLE'을 사용하면 성능이 최고라는 것을 알았습니다. –