CTE와 SubQuery의 차이점은 무엇입니까?


143

이 게시물 에서 다음 절차에서 ROW_NUMBER를 사용하는 방법은 무엇입니까?

하나는 a를 사용 sub-query하고 다른 하나는 a 를 사용 CTE하여 동일한 문제를 해결하는 두 가지 버전의 답변이 있습니다.

이제, CTE (Common Table Expression)'서브 쿼리 ' 를 사용하는 것의 장점은 무엇 입니까 (따라서 쿼리가 실제로 수행하는 것을 더 읽기 쉽게 )

사용하는 유일한 장점 CTE이상은 sub-select내가 실제로 할 수 있다는 것입니다 이름을sub-query. CTE가 단순 (재귀 적이 지 않은) CTE로 사용될 때이 둘 사이에 다른 차이점이 있습니까?


좋은 토론이있는 파생 질문 : stackoverflow.com/q/11169550/781695
사용자

7
IMO하는 CTE를 생각하는 사람은 적은 결합한 서브 쿼리의 거대한 덩어리가 기업 데이터 관리 시스템의 대부분에 걸쳐 사용에 톱니 모양의 쿼리를 혼란의 쓰레기 더미를 볼 수없는 것을 읽을. 사소하지 않은 대규모 쿼리는 일반적으로 하위 쿼리보다 나중에 또는 새로운 눈으로 읽기가 매우 쉬우 며, Postgres의 경우에는 많은 경우 마술처럼 훨씬 더 우수합니다. ([그 이유 는 정반대로 더 이해하기 때문에 아직 이해하지 못한 이유 [( stackoverflow.com/questions/33731068/… ))
zxq9

답변:


102

하위 쿼리 대 단순 (비 재귀) CTE 버전에서는 아마도 매우 유사합니다. 차이점을 파악하려면 프로파일 러와 실제 실행 계획을 사용해야하며 이는 설정에 따라 다릅니다 (따라서 답변을 완전하게 말할 수는 없습니다).

일반적 으로 ; CTE는 재귀 적으로 사용될 수 있습니다. 하위 쿼리는 할 수 없습니다. 따라서 나무 구조에 특히 적합합니다.


1
미안, 내 질문에 더 명확해야했습니다. CTE가 하위 쿼리처럼 사용되는 상황에서 CTE와 하위 쿼리의 차이점은 무엇입니까?
dance2die

2
@Marc Gravell : 프로파일 러의 동작이 보장되지 않기 때문에 CTE의 동작 (평가 측면)과 비교하여 그 이상을 수행 할 수 있습니다.
casperOne 2009

1
이 문장이 CTS와 하위 쿼리의 차이점을 보는 사람들에게 얼마나 의미가 있는지 잘 모르겠습니다 A CTE can be used recursively; a sub-query cannot. 예가 좋았을 것입니다.
Aniket Thakur

88

공통 테이블 표현식 ( 재귀 쿼리에 사용하지 않는 경우) 의 주요 장점은 사용 하려는 모든 위치에서 하위 쿼리를 선언하지 않고 캡슐화하는 것입니다. 한 번만 정의 할 수 있지만 여러 참조가 있습니다 그것에.

그러나 이것이 한 번만 실행된다는 것을 의미 하지는 않습니다 ( 이 답변의 이전 반복에 따라 댓글을 작성한 모든 사람에게 감사드립니다). 쿼리는 여러 번 참조되면 여러 번 실행될 가능성이 있습니다. 쿼리 최적화 프로그램은 궁극적으로 CTE 를 어떻게 해석해야하는지 결정 합니다.


"CTE를 임시 테이블 변수로 생각하십시오"는 CTE가 디스크 나 메모리에 저장되어 있음을 의미합니까?
dance2die

정의에 따라 여러 쿼리에서 CTE 또는 하위 쿼리를 사용할 수 없습니다. 옵티마이
저가

@ AlexCuse : CTE의 맥락을 충분히 명확하게 생각했지만 더 많은 것을 시도하고 명확하게하기 위해 더 추가했습니다.
casperOne 2009

@AlexCuse : CTE 또는 하위 쿼리를 여러 위치에서 사용할 수 있다는 의미도 없습니다. CTE와 옵티마이 저의 차이점은 CTE의 동작은 보장되지만 옵티마이 저의 동작은 보장되지 않는다는 것입니다.
casperOne 2009

그리고 옵티 마이저 초크와 하위 쿼리가 두 번 이상 평가되는 일부 경우가있을 수 있음을 인정할 것입니다. 그런 다음 다시 CTE를 사용합니다.;)
AlexCuse

15

CTE재귀에 가장 유용합니다.

WITH hier(cnt) AS (
        SELECT  1
        UNION ALL
        SELECT  cnt + 1
        FROM    hier
        WHERE   cnt < @n
        )
SELECT  cnt
FROM    hier

@n행 을 반환 합니다 (최대 101). 캘린더, 더미 행 집합 등에 유용합니다.

그들은 또한 더 읽기 쉽습니다 (제 생각에는).

이것 CTEsubqueries는 별개 이며 동일합니다.


MSSQL에서는 WITH 앞에 세미콜론 (;)을 추가해야합니다. 순서대로하면 오류가 발생합니다. 그것은해야;WITH blabla AS ...)
오빈 Nnenanya

2
@ObinnaNnenanya : 배치의 첫 번째 진술이 아닌 경우에만. 세미콜론으로 문을 종료하는 것은 SQL 서버 이전 이외의 현재 버전을 적용하지 않더라도, 어쨌든 좋은 아이디어이며 WITH, MERGE유사한
Quassnoi

10

언급되지 않은 한 가지 차이점은 단일 CTE가 노동 조합의 여러 부분에서 참조 될 수 있다는 것입니다


8

내가 빠진 것이 아니라면 CTE와 하위 쿼리의 이름을 쉽게 지정할 수 있습니다.

가장 큰 차이점은 가독성이라고 생각합니다 (CTE는 중간이 아닌 하위 쿼리를 미리 정의하기 때문에 더 읽기 쉽습니다).

그리고 재귀로 무언가를해야한다면, 하위 쿼리로 그것을하는 데 약간의 어려움이있을 것입니다.)


1
나는 확실히이 아니에요 어떤 (나는 특정 상황에서 실행 계획에 약간의 차이가있을 수 있음을 기대하지만) 비 심미적 인 차이. 깨달을 까?
AlexCuse

2
당신은 할 수 있습니다 이름 열팽창 계수를,하지만 당신은 할 수 별칭 하위 쿼리. 차이점은 여러 별칭을 가진 CTE를 재사용 할 수 있다는 것입니다 (참조 : @Michael Petito의 설명에서 casperOne에 대한 @Michael Petito의 예). 하위 쿼리로 그렇게 할 수있는 방법을 모르겠습니다.
kmote

7

아무도 언급하지 않은 한 가지 중요한 사실은 (적어도 postgres에서) CTE는 최적화 펜스라는 것입니다.

https://blog.2ndquadrant.com/postgresql-ctes-are-optimization-fences/

즉, 전체 쿼리 계획으로 접히지 않고 자체 원자 쿼리로 취급됩니다. 더 나은 설명을 할 수있는 전문 지식이 부족하지만 사용중인 SQL 버전의 의미를 확인해야합니다. 고급 사용자의 경우 최적화 계획을 만들면 쿼리 플래너를 제어하는 ​​데 전문가 수준 인 경우 성능을 향상시킬 수 있습니다. 그러나 99 %의 경우 쿼리 플래너에게 수행 할 작업을 지시하지 말아야합니다. 더 빠를 것이라고 생각하는 것이 더 빠를 것이라고 생각하는 것보다 나쁠 수 있기 때문입니다. :-)


6

다른 응답에 추가하여 하나의 동일한 하위 쿼리를 여러 번 사용한 경우 이러한 모든 하위 쿼리를 하나의 CTE로 바꿀 수 있습니다. 이를 통해 코드를 더 잘 재사용 할 수 있습니다.


4

이해해야 할 사항 중 하나는 이전 버전의 SQL Server (많은 사람들이 여전히 SQL Server 2000 데이터베이스를 지원해야 함)에서 CTE가 허용되지 않으며 파생 테이블이 가장 좋은 솔루션이라는 것입니다.


2

힌트 : (MAXRECURSION n)

당신은 사용하여 특정 문에 허용되는 재귀 수준의 수를 제한 할 수 있습니다 MAXRECURSION힌트 사이의 값 032,767OPTION절을

예를 들어 다음을 시도해 볼 수 있습니다.

OPTION 
      (MAXRECURSION 150)

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