为什么添加此字段会使我的查询运行缓慢?

时间:2017-09-05 12:47:53

标签: sql sql-server

如果我从选择列表中删除一个字段 - 最后一个字段att,则下面的查询在不到一秒的时间内运行。但拥有它会导致查询花费一分钟。有什么想法吗?请注意,左连接内的子查询可以自行运行。

select p.person_id, cfm.family_id, p.nick_name, p.last_name, s.lookup_value as group_role, gm.active, g.group_id, g.group_name, 
g.active as group_active, tg.category, gc.cluster_name, coalesce(a.attendance,0) as att --this field is the culprit
from smgp_group g
join smgp_group_cluster gc on g.group_cluster_id = gc.group_cluster_id
join smgp_member gm on g.group_id = gm.group_id
join core_person p on gm.person_id = p.person_id
join core_family_member cfm on p.person_id = cfm.person_id
join core_lookup s on gm.role_luid = s.lookup_id
join @target_groups tg on g.group_id = tg.group_id
left join (
  select at.person_id, goc.group_id, count(at.attended) as attendance from core_occurrence_attendance at
  join core_occurrence o on at.occurrence_id = o.occurrence_id
  join smgp_group_occurrence goc on o.occurrence_id = goc.occurrence_id
  where goc.group_id in (select group_id from @target_groups)
  and o.occurrence_start_time between @start_date and @end_date
  group by at.person_id, goc.group_id
) a on p.person_id = a.person_id and g.group_id = a.group_id
where tg.category = 'adults' or (tg.category = 'kids' and s.lookup_value in ('Leader-Teacher','Assistant Leader'))

2 个答案:

答案 0 :(得分:1)

尝试运行以下内容 -

SELECT p.persON_id, cfm.family_id, p.nick_name, 
       p.last_name, s.lookup_value as group_role, 
       gm.active, g.group_id, g.group_name, 
       g.active as group_active, tg.cATegory, 
       gc.cluster_name, a.ATtendance 
  INTO #tempDataset
  FROM smgp_group g
  JOIN smgp_group_cluster gc 
    ON g.group_cluster_id = gc.group_cluster_id
  JOIN smgp_member gm 
    ON g.group_id = gm.group_id
  JOIN core_persON p 
    ON gm.persON_id = p.persON_id
  JOIN core_family_member cfm 
    ON p.persON_id = cfm.persON_id
  JOIN core_lookup s 
    ON gm.role_luid = s.lookup_id
  JOIN @target_groups tg 
    ON g.group_id = tg.group_id
  LEFT JOIN (SELECT AT.persON_id, goc.group_id, count(AT.ATtended) as ATtendance FROM core_occurrence_ATtendance AT
               JOIN core_occurrence o 
                 ON AT.occurrence_id = o.occurrence_id
               JOIN smgp_group_occurrence goc 
                 ON o.occurrence_id = goc.occurrence_id
              WHERE goc.group_id IN (SELECT group_id 
                                       FROM @target_groups)
                                        AND o.occurrence_start_time BETWEEN @start_dATe AND @end_dATe
                                      GROUP BY AT.persON_id, goc.group_id) a 
    ON p.persON_id = a.persON_id 
   AND g.group_id = a.group_id
WHERE tg.cATegory = 'adults' or (tg.cATegory = 'kids' AND s.lookup_value IN ('Leader-Teacher','Assistant Leader'))

SELECT persON_id, 
       family_id, 
       nick_name, 
       last_name, 
       group_role, 
       active, 
       group_id, 
       group_name, 
       group_active, 
       cATegory, 
       cluster_name, 
       coalesce(ATtendance,0) AS ATT
  FROM #tempDataset

如果运行缓慢,你可以在临时表上添加一个索引,但我会尝试上面的第一步。

答案 1 :(得分:0)

以下查询在3秒内运行并解决了问题。感谢。

select at.person_id, goc.group_id, count(at.attended) as attendance 
into #a
from core_occurrence_attendance at
join core_occurrence o on at.occurrence_id = o.occurrence_id
join smgp_group_occurrence goc on o.occurrence_id = goc.occurrence_id
where goc.group_id in (select group_id from @target_groups)
and o.occurrence_start_time between @start_date and @end_date
group by at.person_id, goc.group_id 

select p.person_id, cfm.family_id, p.nick_name, p.last_name, s.lookup_value as group_role, gm.active, g.group_id, g.group_name, 
g.active as group_active, tg.category, gc.cluster_name, coalesce(#a.attendance,0) as att--, --this field is the culprit
from smgp_group g
join smgp_group_cluster gc on g.group_cluster_id = gc.group_cluster_id
join smgp_member gm on g.group_id = gm.group_id
join core_person p on gm.person_id = p.person_id
join core_family_member cfm on p.person_id = cfm.person_id
join core_lookup s on gm.role_luid = s.lookup_id
join @target_groups tg on g.group_id = tg.group_id
left join #a on p.person_id = #a.person_id and g.group_id = #a.group_id
where tg.category = 'adults' or (tg.category = 'kids' and s.lookup_value in ('Leader-Teacher','Assistant Leader'))