如何解决慢查询:根据每个组的另一列的 min 和 max 查找值之间的差异
参考Calculate difference between min and max for each column only if higher then 0。
对于选定的odds_type,对于每个相同的fix_id,我正在寻找更新列中MIN和MAX的赔率差异。通过输出,我想取回更新列中的值为最大值的其他行。这就是我的桌子的样子
fix_id | 赔率 | 市场 | 更新 | 输入 |
---|---|---|---|---|
120 | 1.80 | home | 160 | 平均 |
120 | 1.40 | home | 150 | 平均 |
120 | 2.00 | home | 110 | 平均 |
188 | 1.00 | u/o | 200 | REG |
121 | 1.60 | 离开 | 160 | 平均 |
121 | 1.40 | 离开 | 150 | 平均 |
121 | 1.10 | 离开 | 110 | 平均 |
我期待得到什么
fix_id | 赔率 | 市场 | 更新 | 差异 | 输入 |
---|---|---|---|---|---|
120 | 1.80 | home | 160 | -0.2 | 平均 |
121 | 1.60 | 离开 | 160 | 0.5 | 平均 |
我正在使用的代码正在运行,但处理时间太长,而且数据越多,我就会出现超时错误
SELECT a.*,a.odds - b.odds delta
FROM
( SELECT x.*
FROM average_odds x
JOIN
( SELECT fix_id,market,MAX(updated) min_updated
FROM average_odds x where type='avg'
GROUP BY fix_id,market
) y
ON y.fix_id = x.fix_id
AND y.market = x.market
AND y.min_updated = x.updated
) a
JOIN
( SELECT x.*
FROM average_odds x
JOIN
( SELECT fix_id,MIN(updated) min_updated
FROM average_odds x where type='avg'
GROUP BY fix_id,market
) y
ON y.fix_id = x.fix_id
AND y.market = x.market
AND y.min_updated = x.updated
) b
ON b.fix_id = a.fix_id
AND b.market = a.market
ORDER BY `delta` ASC
这里也是 sql 中的解释表,用于查询耗时 15 秒
ID | S TYPE | 表格.. | parti | 输入 | pos_keys | KEY | key len | ref | 行 | 过滤 | 额外 |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | PRIMARY | 衍生3> | null | 全部 | null | null | null | null | 17466 | 100.00 | 使用临时的;使用文件排序 |
1 | PRIMARY | x | null | ref | 修复、修复、市场、更新 | 修复 | 4 | y.fix_id | 596 | 0.11 | 使用 where |
1 | PRIMARY | x | null | ref | 修复、修复、市场、更新 | 修复 | 4 | y.fix_id | 596 | 2.27 | 使用 where |
1 | PRIMARY | 衍生5> | null | ref | auto_key0> | auto_key0> | 31 | y.fix_id,y.market,bobi.x.updated | 10 | 100.00 | 使用索引 |
5 | 派生 | x | null | ref | boki | boki | 4 | const | 17466 | 100.00 | 使用索引条件;使用临时;使用文件... |
3 | 派生 | x | null | ref | boki | boki | 4 | const | 17466 | 100.00 | 使用索引条件;使用临时;使用文件... |
有一个表格定义
字段 | TYPE | NULL | key | 默认 | 额外 |
---|---|---|---|---|---|
fix_id | int(20) | no | MUL | NULL | |
市场 | varchar(20) | no | MUL | NULL | |
标签 | varchar(20) | no | NULL | ||
赔率 | 十进制(4,2) | no | NULL | ||
更新 | int(20) | no | MUL | NULL | |
ev_tstamp | int(20) | no | NULL | ||
TYPE | varchar(20) | no | MUL | NULL | |
market_id | int(20) | no | NULL |
目前查询需要 15 秒才能在大约 75 000 行上执行,但大部分时间我都会出现超时错误。我需要在有 500 000 行的表上使用它,我想知道这是否可能。 P.S 我使用的是 MySQL 5.7.29 并且我在共享服务器上,所以我无法将其升级到 8
解决方法
如果我理解正确,您希望每个 fix_id
where type = 'avg'
的最近两行之间的差异。
如果是这样,我建议使用变量和条件聚合:
select fix_id,max(case when rn = 1 then odds end) as odds,max(case when rn = 1 then market end) as market,max(case when rn = 1 then away end) as away,sum(case when rn = 1 then odds when rn = 2 then - odds end) as diff,max(type) as type
from (select ao.*,(@rn := if(@f = fix_id,@rn + 1,if(@fn := fix_id,1,1)
)
) as rn
from (select ao.*
from average_odds ao
where type = 'avg'
order by ao.fix_id,ao.updated desc
) ao cross join
(select @f := -1,@rn := 0) params
) ao
where rn <= 2
group by fix_id;
,
使用NOT EXISTS
过滤表和相关子查询以获得最早odds
的{{1}}:
update
参见demo。 结果:
fix_id | 赔率 | 市场 | 更新 | 输入 | 差异 |
---|---|---|---|---|---|
120 | 1.80 | home | 160 | 平均 | -0.20 |
121 | 1.60 | 离开 | 160 | 平均 | 0.50 |
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。