Mysql

了解 SQL 聚合效率

  • November 17, 2021

第一個查詢如何在性能方面與第二個備選方案競爭:

查詢一:

select count(*) page_views, 
count(distinct(session_id)) sessions, 
(count(*) / count(distinct(session_id))) pages_per_session
from page_views_table

查詢 2:

select page_views, sessions, (page_views / sessions) pages_per_session from (
   select count(*) page_views, count(distinct(session_id)) sessions 
   from page_views_table
)

我基本上想知道通過使用第一個查詢,數據庫是否需要計算 page_views (count(*)) 和 session (count(distinct(session_id))) 兩次才能獲得 pages_per_session 欄位,因為如果是這樣的話那麼第二個查詢應該更快。那麼第二個查詢實際上是更好的選擇嗎?

我會這樣回答這個問題:第二個查詢會比較慢。

那是因為它需要從“派生表”(FROM ( SELECT ... ))建構一個臨時表,也許將其寫入磁碟,然後讀取它以建構結果表。

作為一般規則,觸摸的數量或*行數決定了性能。*查詢 2 必須接觸臨時表中的行兩次。查詢 1 沒有這樣的臨時表。

一個推論:不要擔心聚合的性能。

我認為基本上你想知道第一個查詢是否會執行count(*)兩次count(distinct(session_id))。答案是否定的,它不會。

第二個查詢將實現子查詢 - 但它只有一行,因此無關緊要。

這兩個查詢應該是等價的。確保您有一個索引session_id,或者第一列是 的索引session_id。否則,值將在記憶體中具體化和排序。這會明顯減慢您的查詢速度。

引用自:https://dba.stackexchange.com/questions/302703