2016-07-15 63 views
0

我怎樣才能得到這些子查詢的rif?如何用聯接替換子查詢?

(所有表都列上創建和LastEdited作爲時間戳)

table Process 
- ID 
- Title 

table ProcessHistory 
- ID 
- ProcessID 
- HistoryID 

table History 
- ID 
- Title (new, open, closed etc.) 

當我試圖讓進程列表與上次狀態稱號的cols我做的:

SELECT DISTINCT Process.*, History.Title AS HistoryTitle, History.ID AS HistoryID 
FROM `Process` 
LEFT JOIN ProcessHistory AS ProcessHistory ON Process.ID=ProcessHistory.ProcessID 
LEFT JOIN History AS History ON HistoryID=ProcessHistory.HistoryID 
WHERE History.ID = (
    SELECT HistoryID FROM ProcessHistory 
    WHERE ProcessID=Process.ID 
    ORDER BY ProcessHistory.ID DESC LIMIT 1 
) 
GROUP BY Process.ID 
ORDER BY Process.ID DESC LIMIT 0, 100 

當我嘗試獲取按特定狀態過濾的列表 (其中最新HistoryID爲1 - 「所有打開的過程」)

SELECT DISTINCT Process.*, History.Title AS HistoryTitle, History.ID AS HistoryID 
FROM `Process` 
LEFT JOIN ProcessHistory AS ProcessHistory ON Process.ID=ProcessHistory.ProcessID 
LEFT JOIN History AS History ON HistoryID=ProcessHistory.HistoryID 
WHERE History.ID=(
    SELECT HistoryID FROM ProcessHistory 
    WHERE HistoryID =1 
    AND ProcessID=Process.ID ORDER BY ProcessHistory.ID DESC LIMIT 1 
) 
GROUP BY Process.ID 
ORDER BY Process.ID DESC LIMIT 0, 100 

由於性能原因,我想擺脫這些子查詢? 我如何替換子查詢?

在此先感謝!

+0

由您創建和加載的sqlfiddle將幫助我們幫助您。注意:加載並不意味着完全加載。這可能意味着每個表格有5到10行數據。 – Drew

+0

這裏的sql小提琴: http://sqlfiddle.com/#!9/3d9001/1 – derRobert

+0

它真的是性能瓶頸還是這是不成熟的,甚至可能是非優化的優化? – e4c5

回答

0

您仍然需要再作選擇濾除歷史過程的其餘部分,但你應該使用derived table,而不是一個子查詢,這樣sqlfiddle

SELECT Process.*, History.Title AS HistoryTitle 
FROM Process 
JOIN (
    SELECT ProcessID, max(HistoryID) as HistoryID 
    FROM ProcessHistory 
    GROUP BY ProcessID 
) PH ON PH.ProcessID = Process.ID 
JOIN History ON History.ID = PH.HistoryID 
ORDER BY Process.ID DESC LIMIT 0, 100 

由於人士Himanshu帕特爾指出, ,「查詢按特定狀態篩選的列表(最新的HistoryID爲1 - 」所有打開的進程「)」的查詢不會產生所需的效果。它將簡單地返回歷史ID爲1的所有進程。請參閱此sqlfiddle

相反,你要使用派生表來獲得這些最新的工藝歷史的ID,用流程加入他們,和歷史上的ID過濾這樣sqlfiddle

SELECT DISTINCT Process.*, History.Title AS HistoryTitle 
FROM Process 
JOIN (
    SELECT ProcessID, max(HistoryID) as HistoryID 
    FROM ProcessHistory 
    GROUP BY ProcessID 
) PH ON PH.ProcessID = Process.ID 
JOIN History ON History.ID = PH.HistoryID 
WHERE PH.HistoryID = 1 
ORDER BY Process.ID DESC LIMIT 0, 100 

另一種方法是創建一個視圖,將ProcessHistory表過濾到每個進程的最新歷史記錄並加入。 YMMV,但在某些情況下,可以通過這種方式改善性能。

3

查詢您張貼不給正確的結果爲每ORDER BY ProcessHistory.ID DESC LIMIT 1

嘗試下面的查詢按查詢

SELECT DISTINCT p.*, h.Title AS HistoryTitle,h.ID AS HistoryID 
FROM 
Process p JOIN ProcessHistory ph ON p.ID=ph.ProcessID and ph.HistoryID=1 
JOIN History h ON h.ID=ph.HistoryID 
GROUP BY p.ID 
ORDER BY p.ID DESC LIMIT 0, 100; 

這裏的sql小提琴的結果:
sql fiddle link

如果希望其他結果然後評論。

0
SELECT * 
FROM Process AS p 
LEFT JOIN (
    SELECT ph.ProcessID, ph.HistoryID, h.Title AS HistoryTitle 
    FROM ProcessHistory AS ph 
    JOIN History AS h ON ph.HistoryID = h.ID 
    WHERE h.ID = 1 
) AS phh ON p.ID = phh.ProcessID 
ORDER BY p.ID DESC LIMIT 100 

Screenshot

0

由於實際子查詢,用於獲取有關每一個「過程」,「最後」行,你既不能把它轉換爲連接,也可以使用它作爲一個單獨的查詢設置一個會話變量。