2016-07-28 70 views
0

我目前的查詢看起來像這樣。我一直在試圖優化它,但到目前爲止我還沒有運氣。 我的目標是讓每個玩家獲得當日和前一天之間stat_value的差異,然後對其進行排序。 目前的代碼工作正常,但我覺得沒有優化。 The?值使用Java填充。跨多行優化MySQL查詢

SELECT t1.stat_value - 
     (SELECT stat_value 
      FROM leaderheadsplayersdata_daily t2 
     WHERE t2.player_id = t1.player_id 
      AND t2.day = ? 
      AND t2.stat_type = ? 
     LIMIT 1 
     ) as sum 
    , (SELECT name 
      FROM leaderheadsplayers 
     WHERE leaderheadsplayers.player_id = t1.player_id 
     LIMIT 1 
     ) 
    FROM leaderheadsplayersdata_daily t1 
    WHERE day = ? 
    AND stat_type = ? 
    ORDER 
     BY sum DESC LIMIT 100 

表結構:

這是包含玩家ID和用戶名的主表。

CREATE TABLE IF NOT EXISTS `leaderheadsplayers` 
(player_id INTEGER PRIMARY KEY AUTO_INCREMENT 
,uuid VARCHAR(36) NOT NULL UNIQUE 
,name VARCHAR(16) NOT NULL 
,last_join DATETIME 
) ENGINE = InnoDB 

這是包含日常數據的表格。

CREATE TABLE IF NOT EXISTS leaderheadsplayersdata_daily 
(player_id INTEGER NOT NULL 
,stat_value DOUBLE NOT NULL 
,stat_type VARCHAR(16) NOT NULL 
,day INTEGER NOT NULL 
,FOREIGN KEY (player_id) REFERENCES leaderheadsplayers(player_id) ON DELETE CASCADE 
,PRIMARY KEY(player_id, stat_type, day) 
) ENGINE = InnoDB 

在此先感謝

+0

描述你的表格結構將有助於建議回答 – evilpenguin

+0

新增數據庫結構。 –

+0

你能提供在查詢中使用EXPLAIN的輸出嗎? – ultrajohn

回答

1

因爲你只有2天,你可以做的leaderheadsplayersdata_daily臺雙連接。

這將是這個樣子:

SELECT 
    p.player_id, 
    p.name, 
    (dc.stat_value-dp.statvalue) AS difference, 
    dc.day, 
FROM leaderheadsplayers p 
JOIN leaderheadsplayersdata_daily dc ON p.player_id = dc.player_id 
JOIN leaderheadsplayersdata_daily dp ON p.player_id = dp.player_id and dp.day = (dc.day-1) 
WHERE dc.day = ?CURRENT_DAY? 
ORDER BY difference DESC 

dc代表 「當前日期」。 dp代表「以前的日期」。 p代表「玩家」。

爲了獲得良好性能,請在player_id(兩個表中)和day列上添加索引。

對不起,我沒有測試,沒有ideea如果我有語法錯誤或東西。另外,請更換?CURRENT_DAY?與實際日期並添加其他條件WHERE條款,根據需要

如果ORDER BY difference DESC不工作,只是做ORDER BY (dc.stat_value-dp.statvalue) DESC

你有很多的子查詢,你看起來像你可以看看一些documentation about JOINs。他們真的很有用。

+0

非常感謝。該查詢現在非常快速。 –

+0

很高興爲您服務。 :) – evilpenguin

-1

或者,您可以嘗試以下操作。讓我知道這個版本如何使用隱式三重聯接票價與上面提到的使用顯式三重聯接的票價。謝謝。

SELECT t3.player_id, improvement FROM 
    (SELECT t1.player_id as player_id, (t1.stat_value - t2.stat_value) as improvement 
     FROM leaderheadsplayersdata_daily t1 INNER JOIN leaderheadsplayersdata_daily t2 
     on t1.player_id = t2.player_id and t1.stat_type = t2.stat_type 
      and t2.day = ? and t1.day = ?) as t3 
    INNER JOIN leaderheadsplayers on 
     t3.player_id = leaderheadsplayers.player_id 
      ORDER BY improvement DESC LIMIT 100;