[英]Query With Multiple Subqueries Efficiency?
我的數據如下所示:
State Sex
---- ---
GA M
GA M
GA F
GA F
GA F
NY M
NY M
NY M
NY M
NY F
NY F
NY F
NY F
NY F
我希望結果是:
我正在使用的查詢是:
select t.state State,
M.count Male,
F.count Female,
count(t.state) Total,
CONCAT(ROUND(CAST(M.count as float)/CAST(count(t.state) as float)*100, 2), '%') as calc
from MyTable t
join
(
select state, count(sex) as count
from MyTable where sex ='M'
group by state) M
on t.state = M.state
join (
select state, count(sex) as count
from MyTable where sex ='F'
group by state) F
ON M.state = F.state
group by t.state, m.count, F.count;
上面的查詢有效,但我想知道我是否以最有效的方式做到了這一點。 這是使用 SQLServer 完成的,但我認為這對於所有 RDBMS 應該是相同的。 鏈接在這里: http://sqlfiddle.com/#!18/7a969/87
使用條件聚合:
select t.state,
sum(case when sex = 'M' then 1 else 0 end) as males,
sum(case when sex = 'F' then 1 else 0 end) as females,
count(*) as total,
avg(case when sex = 'M' then 1.0 else 0 end) as male_ratio
from MyTable t
group by t.state;
我希望這將是幾乎所有數據庫中最快的方法。
這是 SQL 小提琴。
您可以通過從每個 state 的總計數中減去男性人數來計算女性人數。 這樣,只需要一個join
:
with r as (select t.state s, count(*) c from testtable t group by t.state)
select r1.s, t1.m males, r1.c - t1.m females, r1.c total, 100*(t1.m/r1.c) m_percent
from r r1
join (select t.state s, t.sex, count(*) m from testtable t group by t.state, t.sex) t1 on r1.s = t1.s where t1.sex = "M";
Output:
state | 男性 | 女性 | 全部的 | m_percent |
---|---|---|---|---|
遺傳算法 | 2 | 3 | 5 | 40.0000 |
紐約 | 4 | 5 | 9 | 44.4444 |
見演示。
沒有必要將數據分離到Male和Female的表中。 從性能的角度來看,如果子查詢能夠以最佳方式使用索引,則可能有助於提高性能,但實際上您僅對索引值進行聚合的可能性很小。
對於這個簡單的查詢,您可以使用簡單的CASE表達式內聯將Male
/ Female
列表示為BIT
值,然后我們可以在單個聚合中對這些值求和,但是這需要您為Male
定義CASE兩次,因此您可以使用它在Male
列和% Male中。
我們可以使用CROSS APPLY代替內聯CASE作為對每一行解析一次計算的方法,並允許您引用結果:
SELECT t.state State,
SUM(Calcs.IsMale) Male,
SUM(Calcs.IsFemale) Female,
COUNT(1) Total,
CONCAT(ROUND(SUM(Calcs.IsMale)/CAST(COUNT(1) as float)*100, 2), '%') as Calc
FROM MyTable t
CROSS APPLY (SELECT
CASE Sex WHEN 'M' THEN 1 END as [IsMale]
,CASE Sex WHEN 'F' THEN 1 END as [IsFemale]
) as calcs
GROUP BY [State]
這是否更有效? 一般來說,這個執行計划應該比加入多個聚合集簡單得多,但是如果沒有更大的數據集來測試它,就很難說。
無論哪種方式,我都希望這個簡單的 CROSS 應用版本能夠獲勝,因為我們只需要處理一次結果集。
在給定數據集上運行原始和 CROSS APPLY 並查看實際執行計划時,SQL Sever 報告 CROSS APPLY 查詢為批處理相對成本的 25%:
我提前道歉將其作為圖片發布,不確定是否有更好的方式進行討論
這個執行計划報告說 Original Query 是 CROSS APPLY 版本的成本的 3 倍,這可能是由於第一個查詢中的 3 次表掃描,而 CROSS APPLY 版本中的單表掃描。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.