繁体   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