2011-03-29 3 views
2

동일한 하위 쿼리를 두 번 사용하는 SQL 스크립트 (현재 SQLite에 대해 실행되지만 모든 DB 엔진에 대해 작동해야 함)를 사용하고 많은 레코드를 가져올 수 있기 때문에 (테이블에 2 백만 개의 행이 있음) 한 번만 부탁하고 싶습니다. 쿼리의IN 절에 대해이 하위 쿼리를 반복하지 않으려면 어떻게해야합니까?

단축 된 의사 버전은 다음과 같습니다

SELECT * FROM 
    ([the subquery, returns a column of ids]) AS sq 
[a couple of joins, that fetches things from other tables based on the ids] 
WHERE thisorthat NOT IN ([the subquery again]) 
난 그냥 스퀘어 등의 열 이름을 지정하지 않고 함께/괄호없이와/다양한 방법으로 (에서 이름 ( sq)를 사용하여 시도

) 그러나 아무 소용이 없습니다.

이 서브 쿼리를 반복하려면 이 실제로 있습니까?

명확한 설명 : 나는 무엇을 할 수 있는지의 작은 데모로 파이썬과 sqlite가이 일을하고있다,하지만 난 가능한 한 내 확장 할 수있는 솔루션뿐만 아니라 수와 같은 약간의 수정을하고 싶습니다. 실제 상황에서는 데이터베이스에 2 천만 개의 행이 있지만 내 예제에는 더미 데이터가있는 행이 10 개뿐입니다. 따라서 코드는 MySQL에서 완벽하게 최적화됩니다. 즉,에 대해 특별히 으로 최적화 할 필요는 없습니다. 그러나 제가 말했듯이, 수정이 덜 필요할수록 좋습니다.

+1

SQLite는 말할 수 없지만 대부분의 알맞은 RDBMS에서는이를 최적화 할 수 있어야합니다. 일부 제품 (예 : SQL Server, PostgreSQL 등)의 경우 공통 테이블 표현식을 사용하여 텍스트가 한 번만 표시되도록 할 수 있습니다. –

+0

@Damien_The_Unbeliever : SQLlite는 한 손으로 작고 복잡하고 장기간 실행되는 OLAP 유형 쿼리를 지원할 필요가없는 임베디드 데이터베이스이기 때문에 중량 최적화 프로그램은 코드 증가 및 실행 시간 증가에 실제로 가치가 없을 것입니다 짧은 임의 (ad-hoc) 쿼리 –

답변

7

그것이 SQLlite 지원하는 경우 그러나, 나도 몰라, 표준 SQL에 WITH 조항이있다 -하지만 가치 물론 시도의 : 고 말했다

WITH mySubQuery AS 
(
    [the subquery code] 
) 

SELECT * FROM 
    mySubQuery AS sq 
    [a couple of joins, that fetches things from other tables based on the ids] 
WHERE thisorthat NOT IN (mySubQuery) 

, 당신이 무엇을 가능성이 것 몇 천 개가 넘는 데이터 세트에서는 끔찍한 속도가 느릴 수 있으므로 가능하면 리모델링하려고합니다. 일반적으로 두 번째 조인이있는 경우에는 일반적으로 NOT IN을 피해야합니다. 별칭 "스퀘어"하위 쿼리가 필요하십니까 나는 그것이

+0

좋은 제안이지만 WITH는 불행히도 SQLite에서 지원되지 않습니다. –

+0

성능에 관해서는 : 관계 테이블을 통해 하나의 테이블을 자체 조인하고 몇 가지 제약 조건을 필터링 한 다음 다시 같은 조인을 수행하는 것입니다. 제약 조건은 아마도 하위 쿼리에서 수백 행을 필터링하므로 실제로 조인에 백만 행이 없을 것입니다. =) –

+1

하위 쿼리에서 선택해야하는 이유를 아직도 이해하지 못하고 있습니다. 동일한 하위 쿼리가 아니라면 어떻게 필요한지를 그리지 못합니다. 전체 SQL을 게시 할 수 있습니까? 정말 관심이 있다면 최적화 할 수 없습니다. –

0

당신은보기에 SELECT 부분을 넣을 수 있습니다? 예 : OUTER JOIN을 사용하여 다시 작성할 수 있습니다. 다음과 같은 문자 :

SELECT * 
    FROM [the subquery's FROM clause] AS sq 
     RIGHT OUTER JOIN [a couple of tables based on the ids] 
      ON thisorthat = sq.[a column of ids] 
WHERE sq.[a column of ids] IS NULL; 
4

도움이 희망

를 사용하여보기 결과를 필터링 할 수있는 것보다

0

일반적으로 중복을 제거 할 필요가 있습니다. SQL 컴파일러는 두 개의 하위 쿼리가 동일하고 최적화 된 것으로 보이는 경우 한 번만 수행하도록 선택했다는 것을 알 수 있습니다.

또한 원본에 중복을 남겨두면 SQL 컴파일러와 최적화 프로그램에서 서로 다르게 처리 할 수 ​​있습니다. 예를 들어, SQLite의 하위 쿼리 병합 최적화는 한 쌍의 복제본 중 하나에 적용되거나 서로 다르게 적용될 수 있습니다. 9.0 절 하위 쿼리 병합 https://www.sqlite.org/optoverview.html 섹션을 참조하십시오.

관련 문제