2014-02-20 3 views
1

크기가 3GB 인 SQLite3 DB가 있는데이 쿼리를 사용하여 두 제품 사이의 특정 제품에 대한 최신 주문을 가져 오려고합니다.각 제품에 대한 최신 날짜 시간 검색

CREATE TABLE "ProductOrders" (
    "ID" INTEGER NOT NULL UNIQUE, 
    "ProductID" INTEGER NOT NULL, 
    "AdditionalInfo" TEXT, 
    "OrderDateTime" DOUBLE NOT NULL, 
    PRIMARY KEY ("ProductID", "OrderDateTime") 
) 

내가 더 중복 테이블에 없는지 확인하기 위해 ProductIDOrderDateTime에 인덱스를 생성 : 여기

테이블을 만드는 데 사용되는 쿼리입니다.

나는 현재 다음과 같이이 어떻게 사용하고 쿼리 : 그것은을 위해 전체 테이블을 스캔 할 것으로 보인다 그러나

Select ProductID, AdditionalInfo, OrderDateTime 
    From ProductOrders a 
    Where a.OrderDateTime = (Select max(OrderDateTime) 
           From ProductOrders b 
           Where a.ProductID = b.ProductID 
           AND b.OrderDateTime < 40544.5 
           AND b.OrderDateTime > 40539.5 
         ) 

그 쿼리가 잘 작동하고 내가 원하는 것을 정확하게 수행의 'A' 쿼리의 일부. 내 흔적은 다음과 같습니다 :

0|0|0|SCAN TABLE ProductOrders AS a 
0|0|0|EXECUTE CORRELATED SCALAR SUBQUERY 1 
1|0|0|SEARCH TABLE ProductOrders AS b USING COVERING INDEX sqlite_autoindex_ProductOrders_2 (ProductID=? AND OrderDateTime>? AND OrderDateTime<?) 

실행하는 데는 적어도 2 분이 걸립니다. 구조에서 ProductID이 기본 키 1로 표시되고 OrderDateTime이 기본 키 2로 표시된다는 것을 알 수 있습니다. 이것이 이유 일 수 있습니까?

답변

0

은 당신이로 재 작성하는 경우 쿼리가 더 잘 수행 할 것으로 예상 가입 : 서브 쿼리가 ProductOrders의 모든 레코드에 대한 재평가 상관 하위 쿼리와

SELECT a.ProductID, a.AdditionalInfo, a.OrderDateTime 
FROM ProductOrders a 
     INNER JOIN 
     ( SELECT b.ProductID, MAX(b.OrderDateTime) AS OrderDateTime 
      FROM ProductOrders b 
      WHERE b.OrderDateTime < 40544.5 
      AND  b.OrderDateTime > 40539.5 
      GROUP BY b.ProductID 
     ) b 
      ON a.ProductID = b.ProductID 
      AND a.OrderDateTime = b.OrderDateTime; 

을 (당신은 전체 테이블 스캔을보고있는 이유는), JOIN 버전에서는 하위 쿼리가 한 번만 평가되고 결과는 필요에 따라 다시 사용됩니다.

외부 쿼리가 매우 넓고 (전체 테이블) 하위 쿼리가 훨씬 좁기 때문에 (날짜별로 필터링 됨) 외부 쿼리가 매우 좁은 경우 조인 방법이 더 좋을 것입니다. 몇 개의 행을 반환하는 경우), 몇 가지 결과 만 필요할 때 모든 값에 대해 하위 쿼리를 수행하는 것이 좋지 않으므로 상관 된 하위 쿼리 버전이 더 좋을 것입니다.

+0

그리고이 특별한 경우 조인 조건이 인덱스와 일치합니다. –