WHERE 절을 추가하면 뷰가 최적화됩니까?


28

뷰 내부 또는 외부에서 뷰를 필터링하면 차이가 있습니까?

예를 들어이 두 쿼리간에 차이점이 있습니까?

SELECT Id
FROM MyTable
WHERE SomeColumn = 1

또는

SELECT Id
FROM MyView
WHERE SomeColumn = 1

그리고 MyView다음과 같이 정의됩니다

SELECT Id, SomeColumn
FROM MyTable

소스 테이블이 링크 된 서버에있는 경우 답변이 다른가요?

연결된 서버에서 큰 테이블 (44mil 행)을 두 번 쿼리하고 결과를 집계해야하기 때문에 묻습니다. 데이터에 액세스하기 위해 두 개의 뷰를 작성 해야하는지, 각 쿼리마다 하나씩, 단일 뷰와 WHERE절로 벗어날 수 있는지 알고 싶습니다 .


1
테이블이 하나만 있으면 왜 뷰를 사용하겠습니까?
HLGEM

3
@HLGEM 보안?
JNK

2
@HLGEM View에는 실제로 서로 다른 서버의 여러 데이터베이스에 대한 여러 쿼리가 포함되어 있으며 모든 쿼리는로 연결됩니다 UNION ALL. 데이터가 필요할 때마다 UNION 쿼리를 다시 작성하는 것보다 View를 사용하는 것이 훨씬 쉽습니다.
Rachel


1
@datagod 나는 그것을 명심할 것이다. 고마워 :)이 경우, 많은 서버에서 데이터를 수집하고 계산을 실행하며 많은 보고서를 뱉어내는 상당히 작은 앱이있다. 계산 중 일부는 상당히 많은 자원을 소비하기 때문에 자체 데이터베이스가 있으며 다른 모든 것과 분리하고 싶었습니다.
Rachel

답변:


12

이 두 가지 선택의 계획이나 성능에는 전혀 차이가 없어야합니다. 뷰를 쿼리하면 기본 테이블에 대한 쿼리로 확장되어 동일한 검색 또는 스캔이 사용됩니다.

이제의 데이터 형식과 선택성 MyColumn에 따라 기본 테이블에서 필터링 된 인덱스를 만들려는 경우 (SQL Server 2008+로 이동할 때) 성능이 향상 될 수 있지만 뷰를 통해 다시 달라지지는 않습니다. 또는없이.


3
무엇에 대한 이 질문 와 쿼리 이유를 요구하고, where뷰 외부 절은이보기에 넣을 때보다 훨씬 더 오래 걸립니다?
Rachel

1
뷰가 성능이 아닌 경우 구조만을위한 것입니까?
profimedica

1
@profimedica 인덱싱 된 뷰는 성능상의 이유로 생성 될 수 있습니다 (예 : 런타임시 계산 대신 집계와 같은 중간 결과 저장). 뷰가 구체화되지 않은 경우 DRY (다양한 쿼리에서 수행되는 공통 조인 또는 필터), 보안, 난독 화, 스키마 단순화 등 여러 가지 이유로 인해 발생할 수 있습니다.
Aaron Bertrand

5

다음은 차이점이 없다는 것을 보여주는 간단한 예입니다. 데이터베이스가 AdventureWorks데이터베이스입니다.

두 가지보기 정의 :

create view Person.vContactWhere
as

    select *
    from person.Contact
    where ContactID = 24

go

create view Person.vContactNoWhere
as

    select *
    from person.Contact

go

다음은 WHERE뷰 정의에 절이 포함 된 첫 번째 쿼리입니다 .

select *
from person.vContactWhere

실행 계획은 다음과 같습니다.

여기에 이미지 설명을 입력하십시오

그리고 두 번째 쿼리는 WHERE절 정의가 아니라 SELECT쿼리에 있습니다.

select *
from person.vContactNoWhere
where ContactID = 24

그 실행 계획은 다음과 같습니다.

여기에 이미지 설명을 입력하십시오

이 실행 계획에서 볼 수 있듯이 동일한 결과로 동일합니다. 이 유형의 논리 / 디자인이 다른 결과를 출력하는 상황을 모르겠습니다. 그래서 나는 당신이 어느 쪽이든 안전하다고 말하고 개인적 선호 (또는 상점 절차)를 따르고 싶습니다.


1
무엇에 대한 이 질문 와 쿼리 이유를 요구하고, where뷰 외부 절은이보기에 넣을 때보다 훨씬 더 오래 걸립니다?
Rachel

1
@Rachel 나는 gbn이 자신의 게시물과 그가 지적한 기사에서 오히려 잘 설명했다고 생각합니다. 다른 방법을 모르겠습니다.
Thomas Stringer

나는 그 경우에 실행 계획이 같지 않기 때문에 당신의 대답과는 다릅니다.
Rachel

1
@Rachel이 예제의 문제는 누락 된 변환 규칙 입니다. 뷰뿐만 아니라 CTE 및 기타 테이블 표현식에도 적용됩니다. 일반적으로 순위 함수를 포함하는 테이블 표현식으로 술어를 푸시 다운하는 것은 유효하지 않으므로 결과가 변경됩니다. 이 경우에 유효한 이유는 Where절이에 맞기 때문 PARTITION BY입니다. SQL Server 2008에는 SelOnSeqPrj이 특정 사례를 인식 하는 새로운 규칙이있는 것 같습니다 .
Martin Smith


2

내가 읽고 있는 내용을 바탕으로 실행 계획을 결정할 때, SQL은 서브 쿼리와 같은 표준보기를 사용합니다.

예제 쿼리를 사용하면

SELECT Id
FROM MyView
WHERE SomeColumn = 1

어디로 MyView정의

SELECT Id, SomeColumn
FROM MyTable

그것은 같은 실행 계획을 생성해야합니다

SELECT Id
FROM 
(
    SELECT Id, SomeColumn
    FROM MyTable
) as T
WHERE SomeColumn = 1

그러나이 실행 계획은 생성 된 것과 다를 수 있습니다

SELECT Id
FROM MyTable
WHERE SomeColumn = 1

이 답변이 인덱싱 된 뷰에 대해 같은지 확실하지 않습니다.


나는 그것이 명백한 텍스트 대체라고 생각하지 않습니다.
Aaron Bertrand

@AaronBertrand 당신이 옳을 수도 있습니다. 나는 솔직히 모른다 ... 내가 가면서 배우고있다. 인덱스 뷰가 아닌 표준 뷰를 참조하도록 질문을 약간 편집했습니다.
Rachel

@Rachel-대체는 텍스트 레벨이 아닌 대 수화 된 트리에서 발생합니다.
마틴 스미스

@MartinSmith Hrrmm은 내가 말한 것이 아닙니까? 실행 계획이 동일해야하며 텍스트가 동일하지 않아야합니까? "대수 트리"를 이해하고 있는지 잘 모르겠습니다.
Rachel

그것은 Q에 대한 귀하의 의견에 대한 응답으로 "보기에 텍스트를 쿼리에 삽입합니다"와 위의 Aaron의 의견에 대한 답변입니다. 구문 분석 / 컴파일 단계에 대한 정보는 여기를 참조하십시오 . 실제로 귀하의 답변에는 텍스트 대체도 언급되어 있습니다. 이것이 가치있는 구별인지 아닌지. 확실하지 않다! 그러나 sp_refreshview텍스트 대체 개념이 필요하지 않은 이유 가 필요한 이유를 설명합니다 .
Martin Smith
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.