10

내가이 전체 텍스트 색인 테이블에 의존하는 간단한 쿼리를 크롤링옵니다,하지만 난 가 추가 또는 검색과 결합 CONTAINS있을 때 매우 느리게 실행됩니다. 실행 계획에서 볼 수 있듯이 두 가지 전체 텍스트 검색은 성능을 저하시킵니다. 내가 CONTAINS 중 하나만 사용하여 쿼리하거나 둘 다 쿼리하지 않는 경우 쿼리는 잠시 초입니다. 그러나 또는을 쿼리에 추가하면 쿼리가 적합하지 않게됩니다.것을 함유하고 더 OR 검색을 추가하면 쿼리

두 테이블이 너무 넓지는 않습니다 (하나는 42 개, 다른 하나는 21 개, 각 10 개는 FT로 색인 됨). 또는 매우 많은 레코드를 포함 할 수도 있습니다. 두 사람).

나는 세 함께 두 을 분할하여 성능을 해결할 수 있었다 자신의 쿼리를 선택 자신에 검색을 포함하고 다음 UNION. 이 UNION 해결 방법이 유일한 희망입니까?

감사합니다.

SELECT  a.CollectionID 
FROM  collections a 
INNER JOIN determinations b ON a.CollectionID = b.CollectionID 
WHERE  a.CollrTeam_Text LIKE '%fa%' 
      OR CONTAINS(a.*, '"*fa*"') 
      OR CONTAINS(b.*, '"*fa*"') 

실행 계획 (나는 이미지를 게시하기 전에 더 명성을 필요로 추측) : http://yfrog.com/7dslowcontainsj http://desmond.yfrog.com/Himg265/scaled.php?tn=0&server=265&filename=slowcontains.jpg&xsize=640&ysize=640

+1

@ChiragRoy는 SQL2008/R2에 공개 된 PSS 사례가있는 것으로 알려진 문제라고 지적해야합니다. 그러나 다른 사람들이 문제에 부딪혀 대안에 대한 해결책이나 이유가 발견되면 나는 궁금합니다. – scolja

+1

응답으로 하나의 대답을 표시하기위한 프로토콜이 무엇인지 잘 모르겠습니다. 이 경우, UNION은 확실히이 문제를 해결하지만 문제를 해결하고 CONTAINSTABLE을 사용하여 성능을 향상시킬 수 있습니다. 질문에 대한 모든 사람들의 피드백에 정말 감사드립니다. – scolja

답변

6

: 당신이 그것에 대해 정말 있다면, 당신은 뭔가를 시도 할 수 있습니다. 같은 : 우리는 경험에게 동일한 문제를했습니다와 시간에 우리의 질의에 내려 놓고

SELECT  a.CollectionID 
FROM  collections a 
INNER JOIN determinations b ON a.CollectionID = b.CollectionID 
LEFT JOIN CONTAINSTABLE(a, *, '"*fa*"') ct1 on a.CollectionID = ct1.[Key] 
LEFT JOIN CONTAINSTABLE(b, *, '"*fa*"') ct2 on b.CollectionID = ct2.[Key] 
WHERE  a.CollrTeam_Text LIKE '%fa%' 
      OR ct1.[Key] IS NOT NULL 
      OR ct2.[Key] IS NOT NULL 
+2

놀라운 성능. 다시 DISTINCT가 추가되어야하고 CONTAINSTABLE에는 실제 테이블 이름이 필요하지만 약간의 조정만으로 완벽하게 실행되었습니다. 3 가지 방법의 비용 비교 : 29 %, 32 %, 38 % (CONTAINSTABLE, LEUT OUTER JOIN, UNION). 논리적 읽기는 UNION 쿼리의 1/5입니다. 잘 했어. – scolja

+0

'CollectionID' 만 있으면 조인 할 필요조차 없습니다. 'ct1.Key as CollectionID'를 사용할 수 있습니다. –

2
나는 자신의 쿼리로 UNION 각각 제안하려고 했어요,하지만 난 당신의 질문을 읽으면서 나는 것을보고

당신은 그것을 발견했습니다. 나는 더 나은 방법을 생각할 수 없다. 그래서 그것을 사용하면 도움이된다. UNION 메서드는 성능이 좋지 않은 쿼리에 대한 일반적인 접근 방법으로 각 쿼리의 성능이 여러 가지 일 수 있습니다.

+0

+1 UNION을 추천합니다. 참고로 UNION은 대안이 아닌 * 올바른 해결책이라고 말할 수 있습니다. –

+0

UNION 접근법이 매우 도움이된다는 확신에 감사드립니다. 게다가 쿼리가 잘 실행되어 부팅하는 것을 해치지 않습니다. – scolja

+1

그리고 두 조합 문이 매번 상호 배타적 인 경우 추가 성능 imporvements에 UNION ALL을 사용하십시오. – HLGEM

1

아마도 UNION을 사용할 것입니다. 왼쪽이 더 나은 수행하는 것입니다 동등한 CONTAINSTABLE에 가입 있는지 궁금 할 것

SELECT a.CollectionID 
FROM collections a 
    LEFT OUTER JOIN (SELECT CollectionID FROM collections WHERE CONTAINS(*, '"*fa*"')) c 
    ON c.CollectionID = a.CollectionID 
    LEFT OUTER JOIN (SELECT CollectionID FROM determinations WHERE CONTAINS(*, '"*fa*"')) d 
    ON d.CollectionID = a.CollectionID 
WHERE a.CollrTeam_Text LIKE '%fa%' 
    OR c.CollectionID IS NOT NULL 
    OR d.CollectionID IS NOT NULL 
+0

DISTINCT를 추가해야했지만 실제로 UNION 메서드보다 약간 성능이 향상되었습니다.비용 비교는 논리적 읽기 수의 약 2/3 인 46 % ~ 54 %입니다. 흥미 진진한! – scolja

0

심하게 형성되고 - SQL 2005은 우리가 멀리 그것으로 얻을 수 있도록했지만, 2008 않을 것이라고.

결국 IF를 사용하여 호출 된 2 개의 SELECT로 질의를 나눕니다. 다행스럽게도 다른 사람이 동일한 문제를 가지고 있으며 알려진 문제입니다. ~ 150,000 행 + 전체 텍스트가 <에서 1 초 (2005)에서 30 초 (2008 년)로 진행되는 테이블에 대해 쿼리를 보았습니다.

+1

정확히! 이 쿼리는 원래 SQL 2000 시스템에서 정상적으로 작동했지만 일단 SQL 2008로 이전하면이 기능이 나타납니다. 신생 클럽에 오신 것을 환영합니다. – scolja