[英]Optimize SQL with sub queries to?
I have following two tables in the bottom of the post. 我在帖子底部有两个表格。 The siteUsers table have a type column that can be "Member" or "Owner".
siteUsers表的类型列可以为“成员”或“所有者”。 I am looking for a SQL that shows how many members and owners each site has.
我正在寻找一个SQL,该SQL显示每个站点有多少成员和所有者。 I could do something like:
我可以做类似的事情:
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
However this is extreemly slow. 但是,这非常缓慢。 Is there a faster and smarter way?
有没有更快更聪明的方法?
Sites table: 网站表:
SiteId int Unchecked
SPOSiteId uniqueidentifier Checked
Url nvarchar(MAX) Checked
SiteUsers Table: SiteUsers表:
SiteUserId int Unchecked
Type nvarchar(256) Checked
Name nvarchar(512) Checked
Email nvarchar(512) Checked
Host nvarchar(256) Checked
SiteId int Checked
One way is: 一种方法是:
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;
You can do conditional aggregation with JOIN
: 您可以使用
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;
However, you want index on sites(Url), siteuser(type)
for better performance. 但是,您希望在
sites(Url), siteuser(type)
建立索引以获得更好的性能。
If the url
is unique in sites
, then this should be fast with the right indexes: 如果
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;
The right index is on siteusers(siteid, type)
. 正确的索引位于
siteusers(siteid, type)
。 Of course, this assumes that url
is unique which may not be the case. 当然,这假定
url
是唯一的,而事实并非如此。
Use Group By 使用分组依据
select s.Url,su.type, count(*)
from sites s join
siteusers su
on s.siteid = su.siteid
group by s.url,su.type
I'd first check that proper primary keys and indexes are built: 我首先要检查是否构建了正确的主键和索引:
Sites
should have primary key SiteId
Sites
应具有主键SiteId
SiteUsers
should have primary key SiteUserId
SiteUsers
应该具有主键SiteUserId
SiteUsers
should have index on SiteId, type
SiteUsers
应该在SiteId, type
上具有索引SiteId, type
then you can run following query to get results: 然后您可以运行以下查询以获取结果:
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
this way you avoid group by
varchar column 这样您可以避免
group by
varchar列group by
sample fiddle http://sqlfiddle.com/#!18/0b9b7/4 样本提琴http://sqlfiddle.com/#!18/0b9b7/4
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.