ORDER BY가 왜 뷰에 속하지 않습니까?


51

나는 당신이 볼 수 없다는 것을 이해 합니다 . (적어도 SQL Server 2012에서는 작업하고 있습니다) ORDER BY

또한 뷰를 정렬하는 "올바른"방법은 뷰를 쿼리하는 명령문 ORDER BY주위 에 배치하는 것 SELECT입니다.

그러나 실용적인 SQL과 뷰의 사용법에 비교적 익숙하지 않기 때문에 이것이 왜 설계에 의해 수행 되는지 이해하고 싶습니다 . 이력을 올바르게 따라 갔다면 한 번 가능했으며 SQL Server 2008 등에서 명시 적으로 제거되었습니다 (정확한 버전은 인용하지 마십시오).

그러나 Microsoft가이 기능을 제거한 이유에 대해 생각해 볼 수있는 가장 좋은 이유는 "보기가 정렬되지 않은 데이터 수집"이기 때문입니다.

뷰가 정렬되지 않아야하는 합리적이고 논리적 인 이유가 있다고 가정합니다. 뷰가 평평한 데이터 모음 일 수없는 이유는 무엇입니까? 왜 특별히 분류 되지 않은가? (적어도 나에게 / IMHO) 정렬 된 견해를 갖는 것이 완벽하게 직관적 인 상황을 생각해내는 것이 어렵지 않은 것 같습니다.


2
첫 번째 대답은 완벽합니다. 당신이보기를 주문하려면 왜 이것을하지 않는 것이 좋습니다. [열보기]에서 [열]을 선택하십시오. [열]에 따라
Zane

짧은 대답 : "ORDER BY가 테이블에 속하지 않는 것과 같은 이유로"
ypercubeᵀᴹ

답변:


38

물론 인덱싱 된 뷰는 제외됩니다.

뷰가 구체화되지 않았습니다. 데이터가 저장되지 않으므로 어떻게 정렬 할 수 있습니까? 뷰는 SELECT매개 변수가없는 a 만 포함하는 저장 프로 시저와 비슷합니다. 데이터를 보유하지 않고 쿼리 정의 만 보유합니다. 뷰에 대한 서로 다른 참조는 서로 다른 방식으로 정렬 된 데이터를 필요로 할 수 있기 때문에 정의에 따라 정렬되지 않은 행의 콜렉션 인 테이블에서 선택하는 것과 같이이를 수행하는 방법은 외부 쿼리에 순서를 포함시키는 것입니다. .

또한 역사에 대한 약간의 통찰력을 제공합니다. 를 포함하지 않으면 뷰를 넣을 수 없습니다 . 그리고이 경우 표시 되는 행이 아니라에 의해 포함 된 행이 지시되었습니다 . 그냥 그렇다면 2000 SQL 서버에서 일어났다 이었다 거나 , 최적화가 상당히 단순했다 그리고 그것은 일치 일종의와 계획을 생산 끝났다 . 그러나이 행동은 결코 보증되거나 문서화 되지 않았습니다 . 관찰에 기초한 것뿐입니다 . 이는 나쁜 습관 입니다. SQL Server 2005가 나왔을 때 옵티마이 저가 변경되어 다른 계획과 운영자가 사용 되었기 때문에이 동작이 "중단"되기 시작했습니다.ORDER BYTOPORDER BYTOPTOP100 PERCENT{some number >= number of rows in the table}TOP/ORDER BYTOP / ORDER BY인 경우 완전히 무시됩니다 TOP 100 PERCENT. 일부 고객은이 문제에 대해 너무 큰 불만을 제기하여 Microsoft가 이전 동작을 복원하기 위해 추적 플래그를 발행했습니다. 나는 플래그를 사용하지 않기 때문에 플래그가 무엇인지 말하지 않을 것이며 의도가 올바른지 확인하고 싶습니다. 예측 가능한 정렬 순서를 원한다면 ORDER BY외부 쿼리 에서 사용 하십시오.

요점을 요약하고 명확하게하기 위해 : Microsoft는 아무것도 제거 하지 않았습니다 . 그들은 제품을 더 좋게 만들었고 부작용으로 문서화되지 않은 보증되지 않은 행동의 신뢰성이 떨어졌습니다. 전반적으로 제품이 더 좋다고 생각합니다.


여기에 (댓글에) 언급 된 그 TOP수행 결과 세트를 통해 커서 작업. 따라서 명시적인 순서를 가질 수 있습니다.
Tim Schmelter

옵티마이 저가 TOP 100 PERCENT / ORDER BY계획을보고 완전히 제거 할 때 도움이되지 않는 @TimSchmelter . 사용해보십시오.
Aaron Bertrand

그것은 단지 참고 일뿐입니다. 주석의 나머지 부분은 어쨌든 다음과 같습니다. "SELECT TOP x 트릭은 향후 버전의 SQL Server에서 더 이상 사용되지 않을 예정이므로 전혀 사용하지 않는 것이 가장 좋습니다."
Tim Schmelter

@TimSchmelter 그것은 이미 no-op입니다. 기존 코드가 너무 많이 손상되어 새 버전에서 곧 작동을 멈출 것이라고 생각하지 않습니다.
Aaron Bertrand

2
@TimSchmelter 순서 는 행의 순서에 대해 이야기하지 않고 행의 열 순서에 대해 이야기합니다. SQL Server에서는 일반적으로 행의 실제 구현이 매우 명확하기 때문에 행이 튜플 인 행에 대해서는 언급하지 않습니다 (표에는 열을 정의한 순서대로 열이 나열되어 있음).
Aaron Bertrand

9

뷰를 정렬 할 수 있다면 결과의 순서는 무엇입니까?

CREATE VIEW dbo.V1
AS
  SELECT number
  FROM   SomeTable
  ORDER  BY number ASC

GO

CREATE VIEW dbo.V2
AS
  SELECT number
  FROM   SomeTable
  ORDER  BY number DESC

GO

SELECT *
FROM   dbo.V1
       JOIN dbo.V2
         ON V1.number = V2.number 

나는이 포인트를 얻지 못한다. 데이터베이스 뷰를 작성하는 대신 일반 SQL 쿼리를 작성할 수 있습니다. 그렇다면 그 결과의 순서는 무엇입니까? 감사합니다
hqt

7

뷰가 한 순서로 정렬되고 해당 뷰의 선택이 다른 순서로 정렬되는 경우 (뷰 정렬을 모르는 경우) 성능 저하가 발생할 수 있습니다. 따라서 정렬 요구 사항을 사용자에게 두는 것이 더 안전합니다.

또 다른 이유로, 정렬에는 성능 비용이 발생하므로 일부 사용자 만 정렬해야하는 경우보기의 모든 사용자에게 불이익을주는 이유는 무엇입니까?


5

ANSI SQL ORDER BY은 다양한 이유로 인해 가장 바깥 쪽 쿼리 만 허용합니다 . 하나는 subselect / view / CTE가 다른 테이블에 조인되고 외부 쿼리에 ORDER BY자체 가있을 때 발생하는 것입니다.

SQL 서버는 뷰 내에서 그것을 지원하지 않았습니다 ( TOP 100 PERCENT내 의견으로는 대부분 버그를 유발하는 것을 사용하여 트릭하지 않는 한 ).

버그를 트리거하더라도 결과는 신뢰할 수 없었으며 정렬이 항상 예상대로 나오지는 않았습니다.

전체 기술 설명 TOP 100 % ORDER BY 것으로 간주되는 유해한 설명에 대해서는 Query Optimizer 팀의이 블로그 게시물을 참조하십시오 .

이 코드의 기본 계획 구현은 TOP 조작 수행의 일부로 행을 정렬합니다. 이것은 종종 결과가 정렬 된 순서로 리턴되는 것을 의미했으며, 따라서 고객은 행이 정렬되었다는 보장이 있다고 믿게되었습니다. 실제로는 그렇지 않습니다. 정렬 된 순서로 행을 사용자에게 리턴하려면 출력 프리젠 테이션 순서를 보장하기 위해 가장 바깥 쪽 쿼리 블록 (ANSI 당)에서 ORDER BY를 사용해야합니다.


3

뷰는 쿼리 결과에 따라 내용이 결정되는 테이블처럼 동작합니다.

테이블에는 순서가 없습니다. 그들은 단지 행의 가방입니다.

따라서 뷰도 순서가 없습니다. 그러나 특정 ORDER에서 행을 선택하여 정렬 할 수 있습니다.


1
테이블 ... 행 바로 가방이다 - 다음 viwes는 있습니다 가상 의 가방 가상 행 - 전혀 저장 데이터가 없습니다 예 - - 뷰 "존재하지 않는"그들은 단지 "에 쿼리의 정의를 저장하고 기본적으로.
marc_s

1
+1 표와 견해의 동등성은 나에게 견해에 "순서"가 포함되어서는 안되는 주된 이유 인 것 같습니다.
기적 173

1
"보기는 테이블처럼 동작합니다" . "보기는 기본 테이블처럼 동작합니다.보기는 테이블입니다."
ypercubeᵀᴹ

-2

아직 제시되지 않은 한 가지 대답은 "순서 순"이 성능에 큰 영향을 줄 수있는 술어 푸시를 방해 할 수 있다는 것입니다.

예를 들어 큰 데이터 세트를 상위 10 개 / 주문 10 개 라인 요약으로 롤업하는보기가 있습니다.

select * from TopOrderedView; -- Ordered 10 line summary in 5s

강한 술어와 동일한 경우 :

select * from TopOrderedView where <condition>; -- Ordered 2 line summary in still 5s

top / order by가 술어가 파이프 라인에서 이전에 실행되는 것을 차단하므로 여전히 같은 시간이 걸립니다. 이로 인해 불필요한 행이 처리 될 수 있으며 계획은 술어가없는 행과 유사합니다.

주문 전에 푸시가 발생해야하는지 여부는 실제로 개발자의 선택이며 답변을 변경할 수 있습니다. 대부분의 경우 푸시는 논리적 의도입니다.

논리적으로 "상위 100 %"를 사용하면 술어 푸시가 가능하지만 구현은 불행히도이 경우 "순서"를 무시하고 의도를 무시합니다.

실제 사용 사례의 경우 엔진이 "주문하여 주문"을 수행하는 것이 좋습니다. 이렇게하면 뷰 내에서 "순서 기준"을 지정할 수 있으며 (상위 100 % 또는 상위 없음)이 순서는 뷰를 명시 적 순서없이 조인, 집계, 집계없이 직접 선택한 경우에만 사용됩니다. 뷰 체인 등. 위에 나열된 두 경우 모두이 간단한 모델에서 지원 될 수 있습니다.


-6

다음에 쿼리 할 때 순서를 유지하고 순서를 유지하는보기를 작성할 수 있습니다.

상위 99.999999999999 % 선택 * from ..... 주문 기준


1
왜 안돼 SELECT TOP 100 PERCENT ...?
Max Vernon

2
@Max는 아마도이 트릭 과 비슷합니다 . 그렇게 좋은 아이디어는 아닙니다.
Aaron Bertrand

합의, @AaronBertrand - 단지 99.99999999999 :-) 사용할 필요가 없습니다 지적
최대 버논
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.