Mysql
了解 SQL 聚合效率
第一個查詢如何在性能方面與第二個備選方案競爭:
查詢一:
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
。否則,值將在記憶體中具體化和排序。這會明顯減慢您的查詢速度。