2011-05-09 55 views
7

任何人都可以告訴我爲什麼當我將order_by()查詢獲得輸出從INNER JOIN更改爲LEFT OUTER JOINDjango order_by causes LEFT JOIN

有什麼辦法可以保留INNER JOIN -ness?

data = models.RetailSalesFact.objects.values('customer_key__customer_state', 
              'date_key__calendar_month_name') 
data = data.filter(date_key__calendar_year=year) 
data = data.annotate(sales=Sum('sales_quantity')) 
data = data.order_by('date_key__calendar_month_name') 

前:

SELECT Customer_Dimension.Customer_State, Date_Dimension.Calendar_Month_Name, 
     SUM(Retail_Sales_Fact.Sales_Quantity) AS sales 
    FROM Retail_Sales_Fact 
    INNER JOIN Customer_Dimension 
     ON (Retail_Sales_Fact.Customer_Key = Customer_Dimension.Customer_Key) 
    INNER JOIN Date_Dimension 
     ON (Retail_Sales_Fact.Date_Key = Date_Dimension.Date_Key) 
    WHERE Date_Dimension.Calendar_Year = ? 
    GROUP BY Customer_Dimension.Customer_State, 
      Date_Dimension.Calendar_Month_Name 
    ORDER BY Date_Dimension.Calendar_Month_Name ASC 

後:

SELECT Customer_Dimension.Customer_State, Date_Dimension.Calendar_Month_Name, 
     SUM(Retail_Sales_Fact.Sales_Quantity) AS sales 
    FROM Retail_Sales_Fact 
    INNER JOIN Customer_Dimension 
     ON (Retail_Sales_Fact.Customer_Key = Customer_Dimension.Customer_Key) 
    LEFT OUTER JOIN Date_Dimension 
     ON (Retail_Sales_Fact.Date_Key = Date_Dimension.Date_Key) 
    WHERE Date_Dimension.Calendar_Year = ? 
    GROUP BY Customer_Dimension.Customer_State, 
      Date_Dimension.Calendar_Month_Name 
    ORDER BY Date_Dimension.Calendar_Month_Name ASC 
+0

答案更新... – FallenAngel 2011-05-11 06:50:50

回答

1

我猜的ORM是做LEFT JOIN因爲它不能當INNER JOIN的告訴限制條款比訂貨條款更具限制性或限制性。因爲它認爲它需要對每條記錄進行排序,而不管它是否匹配。

您可以使用Raw SQL強制執行INNER JOIN。或者,也許你可以通過在filter之前應用order_by來愚弄ORM?

1

您正在對外部表(date_dimension__calendar_year = year)進行過濾,因此無論您使用內部聯接還是使用左側外部聯接,結果集之間都沒有差異。

order-by在中間結果集上處理 - 如果在內部連接的表上完成,則必須在表結合後完成 - 這意味着讀取一個:組合記錄;閱讀兩個:訂購組合記錄。

但是,如果order-by僅在外連接的表上完成,在這種情況下您只需要這樣做,那麼查詢優化器可能能夠避免兩次讀取整個集合,並且相反,只能讀兩次外表。你的優化器可能會認爲這是處理能力方面的節省。

這只是一個猜測。你的結果集應該以相同的方式出現。我想知道你是否可以用兩種方式計算時間,並且看看哪一個花費更長的時間。

+1

結果集相同,但INNER JOIN和LEFT JOIN之間的時間相當長。這可能不會損害相對較小的數據集上的任何內容,但是當表格填滿時它會產生很大的影響。 – 2011-07-06 16:09:34

+0

那麼inner-join + order-by比left-outer-join + order-by佔用的時間少?我以爲你最初是在比較內部連接(沒有訂單)。 – Chains 2011-07-06 18:46:26

+0

嘗試重新排序您的分組聲明。您的數據集實際上正在排序兩次 - 先按Group-by,然後按順序排序。你可以通過改變group-by來得到你想要的結果:GROUP BY Date_Dimension.Calendar_Month_Name,Customer_Dimension.Customer_State,然後擺脫order by子句? – Chains 2011-07-06 18:48:11