2012-05-03 2 views
4

다음 두 SQL 문은 항상 동일한 결과 집합을 생성합니까?sqlite의 한도 사용 order by 절과 조합 된 SQL 문

1. SELECT * FROM MyTable where Status='0' order by StartTime asc limit 10 

2. SELECT * FROM (SELECT * FROM MyTable where Status='0' order by StartTime asc) limit 10 
+0

이 질문은 SQLite 전용입니까? –

+0

질문은 주로 SQLite를 대상으로합니다. 그러나 같은 시나리오에서 오라클 'rownum'을 사용하는 것에 대한 대답도 나에게 알려준다면 감사 할 것입니다. – nabulke

답변

5

아니오. 첫째, StartTime 열에 UNIQUE 제약이 없기 때문입니다. 따라서 첫 번째 쿼리조차도 항상 동일한 결과를 생성하지는 않습니다.

둘째, StartTime이 같은 두 행이 없어도 대답은 여전히 ​​음수입니다.

첫 번째 문은 항상 StartTime에 주문하고 처음 10 개의 행을 생성합니다. 두 번째 쿼리는 동일한 결과 집합을 생성 할 수 있지만 하위 쿼리의 ORDER BY이 중복됨을 이해하지 못하는 원시적 최적화 프로그램에서만 생성됩니다. 실행 계획에이 주문 단계가 포함되어있는 경우에만

SQLite 쿼리 최적화 프로그램은 (현시점에서) 매우 밝지 않고 그렇게 할 수 있습니다 (실제로는 아무 것도 없습니다. 우리는 SQLite *의 소스 코드를 확인해야합니다). 따라서 두 쿼리가 항상 동일한 결과를 산출하고있는 것처럼 보일 수 있습니다. 아직도, 그것에 의지하는 것이 좋은 생각이 아니다. SQLite의 향후 버전에서 어떤 변경이 이루어질 지 결코 알지 못합니다.

LIMITORDER BY없이 모든 DBMS에 사용하는 것이 좋지 않다고 생각합니다. 이제는 제대로 작동 할 수도 있지만 애플리케이션에서이 쿼리를 얼마나 오래 사용할 지 알 수 없습니다. SQLite가 업그레이드되거나 DBMS가 변경 될 때 주변에 있지 않을 수도 있습니다.

(*) @ Gareth의 링크는 현재 SQLite 코드가 중복 된 순서를 실행할만큼 충분히 벙어리임을 나타내는 실행 계획을 제공합니다.

+1

필자는 원시 옵티마이 저와 마찬가지로 두 번째 쿼리에서 'order by'가 왜 중복되는지 이해하지 못합니다. 설명해 주시겠습니까? – nabulke

+0

그런 하위 쿼리는 (파생 된) 테이블을 반환합니다. 테이블 (기본 테이블, 뷰 또는 파생 된 테이블)에는 암시 적 순서가 없습니다. 일부 DBMS는 파생 서브 쿼리 및/또는 뷰에서 'ORDER BY'를 허용하지 않습니다. –

+0

오라클과'rownum '사용에 관한 [followup 질문] (http://stackoverflow.com/q/10430762/220636)을 올렸습니다. – nabulke

6

예,하지만 서브 쿼리를 주문하는 것은 아마로 얻을 수있는 나쁜 습관이다. 두 번째 예의 하위 쿼리 외부에 ORDER BY을 추가 할 수 있습니다 (예 :

SELECT * 
FROM (SELECT * 
     FROM Test 
     ORDER BY ID ASC 
    ) AS A 
ORDER BY ID DESC 
LIMIT 10; 

SQLite는 여전히 외부 쿼리에 다시 정렬하기 전에, 내부 쿼리에 ORDER BY을 수행합니다. 불필요한 자원 낭비.

각 실행 계획을 볼 수 있도록하기 위해 SQL Fiddle을 수행했습니다.

+0

SQLite가 실제로이를 어떻게 실행하는지 보여주는 실행 계획에 +1. –