[英]Optimizing MySQL query across multiple rows
my current query looks something like this. 我当前的查询看起来像这样。 I've been trying to optimize it but I got no luck so far. 我一直在尝试优化它,但到目前为止我还没有运气。 My goal is to get the difference in stat_value between the current day and the previous day for every player and then order it. 我的目标是获取每个玩家在当前日期和前一天之间的stat_value差异,然后对其进行排序。 The current code works fine, but feels unoptimized to me. 当前的代码工作正常,但对我来说却没有优化。 The ? ? values are filled in using Java. 值使用Java填写。
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
Table structure: 表结构:
This is the main table containing the player id and username. 这是包含玩家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
This is the table containing the daily data. 这是包含每日数据的表。
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
Thanks in advance 提前致谢
Because you only have 2 days, you can do a double join on the leaderheadsplayersdata_daily
table. 由于您只有2天的时间,因此可以对leaderheadsplayersdata_daily
表进行两次leaderheadsplayersdata_daily
。
It would look something like this: 它看起来像这样:
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
stands for "date current". dc
代表“日期电流”。 dp
stands for "date previous". dp
代表“上一个日期”。 p
stands for "player". p
代表“玩家”。
For good performance, add indexes on the columns player_id
(in both tables) and day
. 为了获得良好性能,请在player_id
(在两个表中)和day
列上添加索引。
Sorry, I didn't test, have not ideea if I have syntax errors or stuff. 抱歉,我没有测试,如果我有语法错误或其他东西,还没有想法。 Also, please replace ?CURRENT_DAY?
另外,请替换?CURRENT_DAY?
with the actual day and add other conditions in WHERE
clause, as needed 与实际日期并根据需要在WHERE
子句中添加其他条件
If ORDER BY difference DESC
does not work, just do ORDER BY (dc.stat_value-dp.statvalue) DESC
. 如果ORDER BY difference DESC
不起作用,则只需执行ORDER BY (dc.stat_value-dp.statvalue) DESC
。
You have a lot of subqueries, you look like you could take a look at some documentation about JOINs . 您有很多子查询,看起来您可以看一下有关JOIN的一些文档 。 They're really useful. 它们真的很有用。
Alternatively, you can try the following. 或者,您可以尝试以下方法。 Let me know how this version that uses implicit triple join fare with the one suggested above that uses explicit triple join. 让我知道这个使用隐式三联票价的版本和上面建议的使用显式三联票价的版本。 Thanks. 谢谢。
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;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.