高效获取分区中最大行,避免冗余表访问
在数据查询领域,效率至关重要,尤其是在处理大型表时。一个常见的优化挑战是从表的每个分区中找到特定列中值最大的行。
假设我们需要从SCORES表中获取每个ID在最近一轮(ROUND)中获得的分数:
ID | ROUND | SCORE |
---|---|---|
1 | 1 | 3 |
1 | 2 | 6 |
1 | 3 | 2 |
2 | 1 | 10 |
2 | 2 | 12 |
3 | 1 | 6 |
初始方法:
一种方法是检索所有行,然后过滤掉那些不代表每个ID最大ROUND的行:
<code class="language-sql">SELECT * FROM (SELECT id, round, CASE WHEN (MAX(round) OVER (PARTITION BY id)) = round THEN score ELSE NULL END score FROM SCORES where id in (1,2,3) ) scorevals WHERE scorevals.round is not null;</code>
虽然这种方法有效,但由于存在冗余的表扫描,效率低下。
优化方案:
另一种更高效的方法是使用窗口函数和DISTINCT子句:
<code class="language-sql">SELECT DISTINCT id ,max(round) OVER (PARTITION BY id) AS round ,first_value(score) OVER (PARTITION BY id ORDER BY round DESC) AS score FROM SCORES WHERE id IN (1,2,3) ORDER BY id;</code>
在此方法中,窗口函数max(round) OVER (PARTITION BY id)
计算每个ID的最大ROUND。然后在窗口函数之后应用DISTINCT子句,确保只返回每个ID的最高ROUND行。最后,first_value(score) OVER (PARTITION BY id ORDER BY round DESC)
窗口函数检索与每个ID的最大ROUND关联的第一个SCORE。
这种优化后的方案无需多次表扫描即可获得所需结果,从而显著提高性能。
以上是如何在不进行多表扫描的情况下高效地从分区中选择最大行?的详细内容。更多信息请关注PHP中文网其他相关文章!