외부 적용 및 왼쪽 결합 성능


37

SQL Server 2008 R2를 사용하고 있습니다

방금 SQL에서 APPLY를 보았고 많은 경우 쿼리 문제를 해결하는 방법을 좋아했습니다.

결과를 얻기 위해 2 개의 왼쪽 조인을 사용하는 많은 테이블이 외부 적용 1 개를 얻을 수있었습니다.

로컬 DB 테이블에 소량의 데이터가 있으며 배포 후 코드가 최소 20 배 큰 데이터에서 실행되어야합니다.

외부 적용이 많은 양의 데이터에 대해 2 개의 왼쪽 조인 조건보다 오래 걸릴 수 있습니다.

누구든지 정확히 어떻게 적용하고 어떻게 큰 데이터에서 성능에 영향을 줄지 알 수 있습니까? 가능한 경우 각 테이블의 크기와 비례 관계는 n1 ^ 1 또는 n1 ^ 2에 비례합니다. 여기서 n1은 테이블의 행 수입니다. 1.

왼쪽 조인이 2 개인 쿼리는 다음과 같습니다.

select EC.*,DPD.* from Table1 eC left join
  (
   select member_id,parent_gid,child_gid,LOB,group_gid,MAX(table2_sid) mdsid from Table2
   group by member_id,parent_gid,child_gid,LOB,group_gid

  ) DPD2 on DPD2.parent_gid = Ec.parent_gid
        AND DPD2.child_gid = EC.child_gid
        AND DPD2.member_id = EC.member_id
        AND DPD2.LOB = EC.default_lob
        AND DPD2.group_gid = EC.group_gid
  left join
  Table2 dpd on dpd.parent_gid = dpd2.parent_gid 
            and dpd.child_gid = dpd2.child_gid
            and dpd.member_id = dpd2.member_id 
            and dpd.group_gid = dpd2.group_gid 
            and dpd.LOB = dpd2.LOB
            and dpd.table2_sid = dpd2.mdsid

외부 적용을 사용하는 쿼리는 다음과 같습니다.

select * from Table1 ec   
OUTER APPLY (
      select top 1 grace_begin_date,retroactive_begin_date,Isretroactive
                    from Table2 DPD 
                    where DPD.parent_gid = Ec.parent_gid
                    AND DPD.child_gid = EC.child_gid
                    AND DPD.member_id = EC.member_id
                    AND DPD.LOB = EC.default_lob
                    AND DPD.group_gid = EC.group_gid
                    order by DPD.table2_sid desc
     ) DPD 

답변:


44

누구나 정확하게 작동하는 방식과 그것이 대용량 데이터의 성능에 어떤 영향을 미치는지 알 수 있습니까?

APPLY상관 조인입니다 ( LATERAL JOIN일부 제품 및 최신 버전의 SQL 표준에서는 a라고 함 ). 다른 논리적 구성과 마찬가지로 성능에 직접적인 영향을 미치지 않습니다. 원칙적으로 논리적으로 동등한 구문을 사용하여 쿼리를 작성할 수 있어야하며 옵티마이 저는 입력을 정확히 동일한 물리적 실행 계획으로 변환합니다.

물론이를 위해서는 옵티마이 저가 가능한 모든 변환을 알고 각 변환을 고려할 시간이 필요합니다. 이 프로세스는 현재 우주 시대보다 오래 걸릴 수 있으므로 대부분의 상용 제품은이 방법을 사용하지 않습니다. 따라서 쿼리 구문은 최종 성능에 영향을 줄 수 있으며 종종 더 나은 이유와 이유에 대한 일반적인 설명을하기는 어렵습니다.

OUTER APPLY ( SELECT TOP ... )옵티 마이저에는이 패턴을 동등한 패턴으로 변환하는 논리가 포함되어 있지 않기 때문에 특정 형식은 현재 버전의 SQL Server에서 상관 관계가있는 중첩 루프 조인을 일으킬 가능성이 높습니다 JOIN. 외부 입력이 크거나 내부 입력이 색인화되지 않았거나 필요한 페이지가 메모리에없는 경우 상관 중첩 루프 조인이 제대로 수행되지 않을 수 있습니다. 또한 옵티 마이저 비용 모델의 특정 요소는 상관 된 중첩 루프 조인이 의미 상 동일하지 않아 JOIN병렬 실행 계획을 생성 할 가능성이 적음을 의미합니다 .

단일 왼쪽 조인 및 row_number ()를 사용하여 동일한 쿼리를 만들 수있었습니다.

이것은 일반적인 경우에 더 좋을 수도 있고 그렇지 않을 수도 있습니다. 대표 데이터로 두 가지 대안을 모두 성능 테스트해야합니다. LEFT JOINROW_NUMBER확실히 더 효율적으로 될 가능성이 있지만, 그것은 선택 정확한 쿼리 계획 모양에 따라 달라집니다. 이 방법의 효율성에 영향을 미치는 주요 요소는 필요한 열을 포함하고 PARTITION BYORDER BY절에 필요한 순서를 제공하기위한 색인의 가용성입니다 . 두 번째 요소는 테이블의 크기입니다. 쿼리가 관련 테이블의 상대적으로 작은 부분에 닿으면 효율적이고 잘 인덱스 된 인덱스 가 최적의 인덱스를 APPLY사용하여 성능을 능가 할 수 있습니다 ROW_NUMBER. 테스트가 필요합니다.


2

첫 번째 쿼리는 SQL Server에 대한 하나의 요청만으로 병렬로 실행될 수 있습니다. 모든 레코드를 가져오고 필터 기준에 따라 출력을 제공합니다.

그러나 두 번째 경우에는 행 단위로 실행되고 각 행마다 Table2가 스캔되어 결과에 추가됩니다.

외부 쿼리의 레코드가 적 으면 두 번째 쿼리가 더 좋습니다 (OUTER APPLY). 그러나 첫 번째 쿼리에서 더 많은 데이터를 얻을 수 있으면 첫 번째 쿼리를 사용해야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.