高效取得分區中最大行,避免冗餘表存取
在資料查詢領域,效率至關重要,尤其是在處理大型表格時。一個常見的最佳化挑戰是從表的每個分區中找到特定列中值最大的行。
假設我們需要從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中文網其他相關文章!