簡體   English   中英

使用子查詢來優化SQL?

[英]Optimize SQL with sub queries to?

我在帖子底部有兩個表格。 siteUsers表的類型列可以為“成員”或“所有者”。 我正在尋找一個SQL,該SQL顯示每個站點有多少成員和所有者。 我可以做類似的事情:

select 
    sites.Url,
    (select count(*) from siteusers where type='member' and siteusers.siteid=sites.siteid) as members,
    (select count(*) from siteusers where type='owners' and siteusers.siteid=sites.siteid) as owners
    from sites
    group by sites.url

但是,這非常緩慢。 有沒有更快更聰明的方法?

網站表:

SiteId  int Unchecked
SPOSiteId   uniqueidentifier    Checked
Url nvarchar(MAX)   Checked

SiteUsers表:

SiteUserId  int Unchecked
Type    nvarchar(256)   Checked
Name    nvarchar(512)   Checked
Email   nvarchar(512)   Checked
Host    nvarchar(256)   Checked
SiteId  int Checked

一種方法是:

select s.Url,
       sum(case when su.type = 'member' then 1 else 0 end) as members,
       sum(case when su.type = 'owners' then 1 else 0 end) as owners,
from sites s left join
     siteusers su
     on s.siteid = su.siteid
where su.type in ('member', 'owners')
group by s.url;

您可以使用JOIN進行條件聚合:

SELECT s.Url,
       SUM(CASE WHEN su.type ='member' THEN 1 ELSE 0 END) as members,
       SUM(CASE WHEN su.type ='owners' THEN 1 ELSE 0 END) as owners
FROM sites s INNER JOIN
     siteuser su
     ON su.siteid = s.siteid
GROUP BY s.Url;

但是,您希望在sites(Url), siteuser(type)建立索引以獲得更好的性能。

如果url是唯一sites ,那么這應該是快與正確的索引:

select s.Url,
    (select count(*) from siteusers su where su.type = 'member' and su.siteid = s.siteid) as members,
    (select count(*) from siteusers su where su.type = 'owners' and su.siteid = s.siteid) as owners
from sites s;

正確的索引位於siteusers(siteid, type) 當然,這假定url是唯一的,而事實並非如此。

使用分組依據

 select s.Url,su.type, count(*)

 from sites s join
 siteusers su
 on s.siteid = su.siteid

 group by s.url,su.type

我首先要檢查是否構建了正確的主鍵和索引:

  • Sites應具有主鍵SiteId
  • SiteUsers應該具有主鍵SiteUserId
  • SiteUsers應該在SiteId, type上具有索引SiteId, type

然后您可以運行以下查詢以獲取結果:

select s.url, t.members, t.owners
from Sites s inner join
(
  select
    SiteId, 
    sum(case when Type = 'member' then 1 else 0 end) as members,
    sum(case when Type = 'owners' then 1 else 0 end) as owners
  from SiteUsers
  group by SiteId
) t on s.SiteId = t.SiteId

這樣您可以避免group by varchar列group by

樣本提琴http://sqlfiddle.com/#!18/0b9b7/4

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM