使用子查询来优化SQL?

时间:2019-03-15 19:00:12

标签: sql sql-server tsql

我在帖子底部有两个表格。 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

4 个答案:

答案 0 :(得分:2)

一种方法是:

?

答案 1 :(得分:1)

您可以使用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)上进行索引以获得更好的性能。

如果urlsites中是唯一的,那么使用正确的索引应该很快:

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是唯一的,而事实并非如此。

答案 2 :(得分:1)

使用分组依据

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

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

 group by s.url,su.type

答案 3 :(得分:1)

我首先要检查是否构建了正确的主键和索引:

  • Sites应该具有主键SiteId
  • SiteUsers应该具有主键SiteUserId
  • SiteUsers应该在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列

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