我的查询需要很长时间才能完成查找列值差异最大的行对由另一列分组
My query is taking too long to finish for finding the pair of rows where the difference of columns value is maximum group by another column
说,我有一个 table 这样的:
我想找到每个会话中性能差异最高的一对中心,如下所示:
我有以下查询,
select
t1.session,
t1.center center1,
t2.center center2,
t1.performance - t2.performance performance
from mytable t1
inner join mytable t2 on t1.session = t2.session
where t1.performance - t2.performance = (
select max(t11.performance - t22.performance)
from mytable t11
inner join mytable t22 on t11.session = t22.session
where t11.session = t1.session
)
它可以工作,但需要很长时间,对于 20 列和 200 行的 table 几分钟。 如何修改查询以更快地实现相同的输出?
使用row_number()
:
select session, center1, center2, performance
from (select t1.center as center1, t2.center as center2,
(t1.performance - t2.performance) as performance,
row_number() over (partition by t1.session order by (t1.performance - t2.performance) desc) as seqnum
from mytable t1 join
mytable t2
on t1.session = t2.session
where seqnum = 1;
或者为了更好的表现。最大差值是最大值减去最小值。你想要中心,这是一个没有子查询的方法:
select session,
max(case when seqnum_desc = 1 then center end) as center1,
max(case when seqnum_asc = 1 then center end) as center2,
max(performance) - min(performance)
from (select t.*,
row_number() over (partition by session order by performance) as seqnum_asc,
row_number() over (partition by session order by performance desc) as seqnum_desc
from mytable t
where 1 in (seqnum_asc, seqnum_desc)
group by session
select
t1.session,
t1.center center1,
t2.center center2,
t1.performance - t2.performance performance
from mytable t1
inner join mytable t2
on t1.session = t2.session
WHERE t1.performance = (SELECT MAX(performance)
FROM mytable t3 WHERE t3.session = t1.session)
AND t2.performance = (SELECT MIN(performance)
FROM mytable t3 WHERE t3.session = t2.session)
// Im thinking this will solve the border case when performance is a tie
// and difference 0 will return 2 rows
AND (CASE WHEN t1.performance = t2.performance
THEN CASE WHEN t1.center < t2.center
THEN 1
ELSE 0
END
ELSE 1
END) = 1
只要您在 performance
和 session
上有索引就可以了。
按会话分组并采用组的最小和最大性能似乎合乎逻辑。
不幸的是,实际的中心在这里需要 subquery/join。
select g.session as Session,
(select min(center) from mytable
where session = g.session and performance = g.maxim) as Center1,
(select min(center) from mytable
where session = g.session and performance = g.minim) as Center2,
g.maxim - g.minim as Performance
from (select
t1.session,
min(t1.performance) as minim,
max(t1.performance) as maxim
from mytable t1
group by t1.session)
as g
确保会话和性能指标。
select distinct(session) * from (
select t1.session, t1.center, t2.center,
(case when t1.performance > t2.performance then (t1.performance-t2.performance) else (t2.performance-t1.performance))as performance_diff
from mytable t1, mytable t2
where t1.session=t2.session and t1.center!=t2.center) as T1 order by session,performance_diff desc limit 1;
说,我有一个 table 这样的:
我想找到每个会话中性能差异最高的一对中心,如下所示:
我有以下查询,
select
t1.session,
t1.center center1,
t2.center center2,
t1.performance - t2.performance performance
from mytable t1
inner join mytable t2 on t1.session = t2.session
where t1.performance - t2.performance = (
select max(t11.performance - t22.performance)
from mytable t11
inner join mytable t22 on t11.session = t22.session
where t11.session = t1.session
)
它可以工作,但需要很长时间,对于 20 列和 200 行的 table 几分钟。 如何修改查询以更快地实现相同的输出?
使用row_number()
:
select session, center1, center2, performance
from (select t1.center as center1, t2.center as center2,
(t1.performance - t2.performance) as performance,
row_number() over (partition by t1.session order by (t1.performance - t2.performance) desc) as seqnum
from mytable t1 join
mytable t2
on t1.session = t2.session
where seqnum = 1;
或者为了更好的表现。最大差值是最大值减去最小值。你想要中心,这是一个没有子查询的方法:
select session,
max(case when seqnum_desc = 1 then center end) as center1,
max(case when seqnum_asc = 1 then center end) as center2,
max(performance) - min(performance)
from (select t.*,
row_number() over (partition by session order by performance) as seqnum_asc,
row_number() over (partition by session order by performance desc) as seqnum_desc
from mytable t
where 1 in (seqnum_asc, seqnum_desc)
group by session
select
t1.session,
t1.center center1,
t2.center center2,
t1.performance - t2.performance performance
from mytable t1
inner join mytable t2
on t1.session = t2.session
WHERE t1.performance = (SELECT MAX(performance)
FROM mytable t3 WHERE t3.session = t1.session)
AND t2.performance = (SELECT MIN(performance)
FROM mytable t3 WHERE t3.session = t2.session)
// Im thinking this will solve the border case when performance is a tie
// and difference 0 will return 2 rows
AND (CASE WHEN t1.performance = t2.performance
THEN CASE WHEN t1.center < t2.center
THEN 1
ELSE 0
END
ELSE 1
END) = 1
只要您在 performance
和 session
上有索引就可以了。
按会话分组并采用组的最小和最大性能似乎合乎逻辑。 不幸的是,实际的中心在这里需要 subquery/join。
select g.session as Session,
(select min(center) from mytable
where session = g.session and performance = g.maxim) as Center1,
(select min(center) from mytable
where session = g.session and performance = g.minim) as Center2,
g.maxim - g.minim as Performance
from (select
t1.session,
min(t1.performance) as minim,
max(t1.performance) as maxim
from mytable t1
group by t1.session)
as g
确保会话和性能指标。
select distinct(session) * from (
select t1.session, t1.center, t2.center,
(case when t1.performance > t2.performance then (t1.performance-t2.performance) else (t2.performance-t1.performance))as performance_diff
from mytable t1, mytable t2
where t1.session=t2.session and t1.center!=t2.center) as T1 order by session,performance_diff desc limit 1;