하위 쿼리에서 ORDER BY의 데이터베이스 구현


10

- (맵 서버 나 응용 프로그램 사용하고 http://mapserver.org/ 문 BY 순서는 내부 쿼리에 그래서, 랩이 문을 SQL 있음을). 예 :

SELECT * FROM (
        SELECT ID, GEOM, Name
        FROM t
        ORDER BY Name
        ) as tbl

응용 프로그램에는 다양한 데이터베이스 드라이버가 있습니다. 주로 MS SQL Server 드라이버와 SQL Server 2008을 사용합니다. 하위 쿼리에서 ORDER BY가 발견되면 오류가 발생합니다.

MS Docs (SQL Server 2000 용이지만 여전히 적용되는 것처럼 보입니다) :

뷰, 인라인 함수, 파생 테이블 또는 서브 쿼리에서 ORDER BY 절을 사용하는 경우 순서가 지정된 출력을 보장하지 않습니다. 대신 ORDER BY 절은 Top 연산자에 의해 생성 된 결과 집합이 일관된 구성을 갖도록 보장하는 데만 사용됩니다. ORDER BY 절은 가장 바깥 쪽 SELECT 문에 지정된 경우에만 정렬 된 결과 세트를 보장합니다.

그러나 Postgres (9)에서 실행되는 동일한 유형의 쿼리와 Oracle은 하위 쿼리에 정의 된 순서대로 결과를 반환합니다. Postgres에서 쿼리 계획은 결과가 정렬되어 있고 Postgres 릴리스 노트에는 하위 쿼리 순서가 사용됨을 나타내는 항목이 포함되어 있습니다.

하위 쿼리 ORDER BY가 상위 쿼리와 일치 할 때 정렬 방지

http://en.wikipedia.org/wiki/Order_by 상태 :

일부 데이터베이스 시스템은 부속 선택이나보기 정의에서 ORDER BY 절의 스펙을 허용하지만 영향이 없습니다.

그러나 내 자신의 쿼리 계획 확인에서 :

  • SQL Server 2008은 하위 쿼리에서 ORDER BY를 지원하지 않습니다
  • Postgres 9는 하위 쿼리에서 ORDER BY를 지원합니다
  • Oracle 10g는 하위 쿼리에서 ORDER BY를 지원합니다

내 질문에 Postgres와 Oracle이 하위 쿼리에서 정렬을 허용하지 않는다는 것을 공식적으로 확인하거나 거부 할 수있는 링크가 있습니까?


2
특정 결과를 관찰한다고해서 결과가 보장되는 것은 아닙니다. 일관성을 원한다면 외부에 주문하십시오. 기간.
Aaron Bertrand

이상적으로 이것이 구현 될 것입니다. 그러나이 단계에 도달하려면 핵심 논리 및 많은 데이터베이스 드라이버가 변경됩니다. 이 문제는 몇 년 동안보고되지 않았으므로 일부 DB는 하위 쿼리에서 ORDER BY를 일관되게 구현하는 것처럼 보입니다. 가능한 경우 어떤 것을 아는 것이 좋을 것입니다.
geographika

2
@geographika 지금까지 일부 DBMS가 일관되게 수행하더라도 향후에도 동일한 작업을 계속할 것이라는 보장은 없습니다. 예를 들어, 5.6에서 MySQL의 최적화 기능 (및 MariaDB 5.3)의 개선으로 ORDER BY하위 쿼리에서 중복을 식별 하고 불필요한 정렬을 수행하지 않습니다.
ypercubeᵀᴹ

답변:


15

응용 프로그램 이 하위 쿼리 안에 넣지 않도록 해야합니다 ORDER BY(처음에는 불필요한 하위 쿼리를 사용하지 않는 옵션이있을 수 있음). 이미 발견 한 것처럼이 구문은 SQL Server가없는 SQL Server에서 지원되지 않습니다 TOP. 그리고로 TOP행을 남기지 않으려면를 사용 TOP 100 PERCENT하면 ORDER BY최적화 된 것을 렌더링 할 수 있습니다.

Oracle과 PostGres에서 구문이 지원 된다고해서 반드시 준수한다는 의미는 아닙니다. 그리고 일부 시나리오에서이를 준수한다고 간주한다고해서 새로운 버전이 나오거나 데이터, 통계, 쿼리 자체 또는 환경에 미묘한 변화가있을 때 계속 준수한다는 의미는 아닙니다.

의심의 여지없이 주문에 대한 보증 을 원한다면 ORDER BY가장 바깥쪽에 쿼리 를 넣어야 한다는 것을 확신 할 수 있습니다. 이것은 어떤 플랫폼을 사용하든 밀접하게 지키는 교리 여야합니다.

공식적으로 지원되지 않는 링크를 요청하고 있습니다. 이것은 자동차 소유자 매뉴얼에서 자동차가 날 수 없다는 공식 진술을 보는 것과 같습니다.


감사. MSSQL이 오류를 발생시키는 올바른 방법이라고 생각합니다. 내부 쿼리에서 정렬을 지원하고 구현하는 것은 핵심 SQL 원칙에 위배 될 때 재난의 비법으로 보입니다. 그래도 자동차 비유에 대해 확실하지 않습니다-자동차가 실제로 날고있는 동안 매뉴얼에서 그것을 추가해야합니다 ..
geographika

-1

나는 이것이 느슨하다는 것을 인정하지만, 꼬집어 있다면 하위 쿼리에서 최상위 행 수를 반환하십시오. 상위 100 %를 반환해도 효과가 없지만 문제를 해결하려면 행 수를 쿼리하여 변수로 TOP에 전달할 수 있습니다. 호환성 수준 80으로 설정된 데이터베이스에서 이것을 테스트 했으므로 SQL 2000에서 작동해야한다고 생각합니다.

SELECT * FROM (
        SELECT TOP (100000) ID, GEOM, Name
        FROM t
        ORDER BY Name
        ) as tbl

나는 이것을 원래 시도했지만 작은 데이터 세트에 대해서는 잘 정렬 된 것처럼 보였습니다. 그러나 매우 큰 레코드 집합을 얻을 때 SQL Server 2008R2에서 정렬이 다시 무작위로 변경되었습니다. 메모리 / 페이지 크기와 관련이 있습니까?
geographika

도움이되지 않아서 죄송합니다. 상위 100 %를 선택하면 정렬이 무작위로 되돌아갔습니다.
DBNull

쿼리가 병렬로 진행되는 경우, 특히 Name고유하지 않은 경우에는 작동하지 않습니다 . 옵티마이 저가 다른 키 열 순서로 다른 인덱스를 선택하면 계속 작동하지 않을 수 있습니다.
Erik Darling
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.