2013-06-04 3 views
2

저는 최근에 나에게 아주 새로운 것을 배웠습니다 - 전체 인덱스.전체 텍스트 인덱스 - 여러 테이블에서 큰 성능 저하

두 개의 개별 테이블에 대해 동일한 매개 변수에 대해 두 개의 개별 쿼리 (CONTAINSTABLE 사용)를 실행할 수있는 것처럼 보입니다.하지만 두 개의 테이블을 결합 할 때 거의 즉각적인 응답 (하위 10ms)이 발생하지만 쿼리에는 1.3 초가 걸립니다. 또는 130+ 배 느린 !!

다음은이 질문의 목적에 맞게 단순화 된 쿼리입니다.

쿼리 1 :

SELECT 
    * 
FROM 
    dbo.FooBar FB 
    INNER JOIN dbo.FooBalls FBS on FB.ID = FBS.ID 
    LEFT JOIN CONTAINSTABLE(dbo.FooBar, (Col1, Col2, Col3), @query) FBCONT ON FB.ID = FBCONT.[KEY] 
WHERE 
    FBCONT.[KEY] IS NOT NULL 

질의 2 :

SELECT 
    * 
FROM 
    dbo.FooBar FB 
    INNER JOIN dbo.FooBalls FBS on FB.ID = FBS.ID 
    LEFT JOIN CONTAINSTABLE(dbo.FooBalls, (Col1), @query) FBSCONT ON FBS.ID = FBSCONT.[KEY] 
WHERE 
    FBSCONT.[KEY] IS NOT NULL 

쿼리 결합 : 아마도

SELECT 
    * 
FROM 
    dbo.FooBar FB 
    INNER JOIN dbo.FooBalls FBS on FB.ID = FBS.ID 
    LEFT JOIN CONTAINSTABLE(dbo.FooBar, (Col1, Col2, Col3), @query) FBCONT ON FB.ID = FBCONT.[KEY] 
    LEFT JOIN CONTAINSTABLE(dbo.FooBalls, (Col1), @query) FBSCONT ON FBS.ID = FBSCONT.[KEY] 
WHERE 
    (FBCONT.[KEY] IS NOT NULL OR FBSCONT.[KEY] IS NOT NULL) 

내 입술 earch는 무언가를 놓쳤지 만 누군가 두 항목을 함께 사용하면 성능이 130 배 이상 저하되는 이유에 대한 지표를 얻을 수 있습니까?

참고 : 나는 시청에 관련 인덱스를 확인했습니다

  • 존재 - 개별 쿼리의 속도에 의해 확인.
  • 실제로 프로세스에 더 많은 조인이 포함됩니다. 그러나 쿼리와 관련된 테이블과 완전히 연결이 끊어졌으며 100,000 개가 넘는 레코드로 결과를 검색 할 때 응답이 10ms 미만입니다.
  • CONTAINSTABLE을 개별 CONTAINS 문으로 대체하려고 시도했습니다. 성능이 크게 저하되어 내 연구가 나를 이끌 것으로 예상됩니다.
  • 쿼리하는 두 테이블의 네 열만을 참조하는 카탈로그가 구성되었습니다.
  • @query 매개 변수는 현재 NVARCHAR (50)로 설정되어 있습니다. 암묵적인 변환이 필요하지 않으므로 NVACHAR을 사용하면 속도가 빠릅니다.
  • 두 쿼리 모두에서 더러운 UNION ALL을 별도로 수행 할 수 있음을 알고 있지만 가능하다면 함께 해킹하지 말고 더 나은 쿼리를 작성하는 것이 좋습니다. 또한 UNION ALL은 @query 값이 하나의 레코드에 연결된 별도의 테이블에서 두 개의 열에있을 경우 잠재적 인 중복을 남겨 둡니다.

더 많은 제안이 많이 접수 될 것입니다.

+0

실제 쿼리 실행 계획을 어딘가에 게시하고 링크를 게시하십시오. 또한, 사용중인 SQL Server의 버전과 containstable을 수행하고있는 각 테이블의 행 수는 얼마나됩니까? – StrayCatDBA

+0

통계를 설정합니다. 컴파일 시간과 실행 시간은 얼마나 걸립니까? – StrayCatDBA

+0

@StrayCatDBA, 해당 Sql Server 2012. 불행히도 쿼리 실행을 게시 할 수 없습니다 - 비공개 등 - 이상적이지는 않지만 필요합니다. 그러나 뭔가 갑자기 나에게 와서 - 문제가 실제로 남아있는 다른 네 개의 조인에 나타났습니다 - 사용자 priveledges를 기반으로 결과를 제한하는 데 사용되는, 나는 조인을 제거하고 아래의 하위 쿼리를 기반으로 결과를 제한하여 발견 where 절은 속도가 10 배 증가했습니다. 내 대답을 게시 할 것입니다. 회신 해 주셔서 감사합니다. –

답변

0

귀하의 질문에 대한 의견은 관련없는 쿼리의 일부를 다시 작성함으로써 만족스러운 수준으로 성능을 향상시킬 것을 제안합니다 (질문에 표시되지 않음).

작동하는 것은 충분히 공평하지만 다른 관련없는 쿼리 부분이 일정하게 유지되는 경우 두 개의 개별 쿼리와 결합 된 쿼리가 왜 크게 다른지 설명하지 않습니다.

쿼리 계획 및 통계 결과를 보지 않고도 자신있게 말할 수는 없습니다.

  1. 하나 또는 둘 모두 ID 열 (FooBar에서와 FooBalls)이 후 설정 행의 고유하지 않은 될 수있다 : 그러나 나는 전적으로 추론에 SQL 쿼리를 작성하는 방법에 대한 기반 두 가지 가능성을 생각할 수 2 개의 테이블이 내부 결합되었습니다. 두 개가 아닌 CONTAINSTABLE 결과 집합에 조인하는 것은 단일 조인보다 많은 양의 레코드를 "번식"시킬 수 있습니다. 더 큰 결과 세트는 클라이언트로 다시 전달되고 표시되는 데 더 오래 걸립니다. 테스트하려면은 두 개의 개별 쿼리에서 반환 된 행 수를 비교하고 WHERE 절이 생략 된 경우 각 개별 쿼리의 행 수와 비교해보십시오. 큰 행 수는 일반적으로 더 긴 쿼리 경과 시간 (다른 모든 것은 동일 함)을 제안합니다.

  2. 각 별도의 쿼리는 왼쪽 외부 조인으로 작성되었지만 결과 집합은 조인이 성공한 행만 포함하도록 제한됩니다. 이것은 사실상 내부 조인입니다. SQL Server의 쿼리 계획자는이 사실을 확인하고 내부 조인이 지정된 것처럼 실행 계획을 선택하는 것입니다. 반대로 조합 된 쿼리에는 중 하나 인이 포함되어있는 행이 필요합니다. 둘 중 하나 일 필요는 있지만 둘 다 성공한 것은 아닙니다. 실행 계획은 이러한 조인에 대해 서로 다른, 느린 방법을 사용합니다. 테스트하려면 실행 계획을 살펴보고 왼쪽 조인 대신 요청 된 내부 조인을 사용하는 별도 쿼리의 실행 계획과 비교하십시오.