2009-12-22 48 views
1

我有一個查詢,我已經成爲一個MYSQL視圖。這個特定的視圖是我們應用程序的核心,所以我們正在調整它。在Map_Id,User_No,X,Y上有一個主鍵。我很樂意調整SQL Server查詢,但不完全確定MySql在這方面的工作方式。將它放在一個包含點和update_stamp的索引上會有幫助嗎?這張表上的讀數是90%,所以它有很多的插入,它不會與讀取的數量進行比較。mysql查詢調優

說明:獲取與每個x積分最高的人,Y座標在給定的地圖。由誰擁有最新的更新戳記,然後通過用戶ID進行打破。

SELECT GP.Map_Id AS Map_Id,GP.User_No AS User_No,GP.X AS X,GP.Y AS Y, GP.Points AS Points,GP.Update_Stamp AS Update_Stamp 
    FROM (Grid_Points GP LEFT JOIN Grid_Points GP2 
     ON (
     (
     (GP2.Map_Id = GP.Map_Id) AND (GP2.X = GP.X) AND (GP2.Y = GP.Y) AND 
     ((GP2.Points > GP.Points) OR ((GP2.Points = GP.Points) AND (GP2.Update_Stamp > GP.Update_Stamp)) OR 
     ((GP2.Points = GP.Points) AND (GP2.Update_Stamp = GP.Update_Stamp) AND (GP2.User_No < GP.User_No))) 
     ) 
) 
) 

WHERE ISNULL(GP2.User_No); 

回答

3

哇,你真的很喜歡用括號。 :-)

你說得對,複合指數可能有幫助。你甚至可以將它作爲覆蓋索引。可能是Grid_Points(Map_Id,X,Y)Grid_Points(Points,Update_Stamp,User_No)上的索引就是我的嘗試。

始終以EXPLAIN測試查詢優化,以查看是否優化使用索引。閱讀該文檔部分,直到您理解EXPLAIN報告中的隱藏筆記。

EXPLAIN報告可能會告訴你它決定使用哪個索引。您應該知道,MySQL在給定查詢中每個表只使用一個索引。

這是我會怎麼寫查詢,ANDOR而不是這麼多的嵌套的括號之間依靠的優先順序:

SELECT GP.Map_Id, GP.User_No, GP.X, GP.Y, GP.Points, GP.Update_Stamp 
FROM Grid_Points GP LEFT JOIN Grid_Points GP2 
    ON GP2.Map_Id = GP.Map_Id AND GP2.X = GP.X AND GP2.Y = GP.Y 
    AND (
     GP2.Points > GP.Points 
     OR 
     GP2.Points = GP.Points 
     AND GP2.Update_Stamp > GP.Update_Stamp 
     OR 
     GP2.Points = GP.Points 
     AND GP2.Update_Stamp = GP.Update_Stamp 
     AND GP2.User_No < GP.User_No 
    ) 
WHERE GP2.User_No IS NULL; 

您使用我最喜歡的方法尋找最大的正每組在MySQL中。 MySQL並沒有很好地優化GROUP BY(它通常會產生一個臨時表,它會被序列化到磁盤),所以你使用的左外連接解決方​​案通常要好得多,至少對於MySQL來說。在其他品牌的RDBMS中,這種解決方案可能沒有這樣的優勢。

+0

其實我討厭所有的括號,但我不得不導出視圖來查看結構,並將它放入。我做了解釋並看到它正在進行全面掃描。我會嘗試一個覆蓋指數。非常感謝!! – Codezy 2009-12-22 20:24:02

+0

感謝您的信息。順便說一句,我測試了我的解決方案的一些樣本數據,它的速度差不多,我不知道這樣做的另一種方式。正如你所提到的真正的解決方案是在索引中,Map_Id,X,Y比Points,Update_Stamp,User_No更有幫助 請注意解釋這個查詢是如何工作的/我可以在這種風格下閱讀? – MindStalker 2009-12-22 20:34:14

+0

請按照StackOverflow中的「每個組的最大n」標籤。解決方案有幾十個類似的問題。 – 2009-12-22 20:37:14

1

我不會匹配自己,我會做它作爲「分組依據」,然後可能匹配回去拿的人是誰。

SELECT MAP_ID,X,Y,最大值(點) FROM Grid_Points GROUP BY MAP_ID,X,Y;

這會給你MAP_ID,X和Y,那麼最大的點的表格。 然後,您可以將這些結果加回到Grid_Points,以查找哪些用戶是=這些點。

+0

此外,你想索引(不是一個唯一的索引只是一個指數) Map_Id,X,Y,點 – MindStalker 2009-12-22 20:00:39

+0

我們確實從最大和組開始,並改爲我們當前的方法。我會盡力看到性能差異。 – Codezy 2009-12-22 20:24:57