如何最小化多个子查询?

时间:2013-07-18 12:07:29

标签: sql sql-server tsql

我有以下查询有点慢,因为你可以看到where子句中有几个嵌套查询,有人能想出更好的解决方案吗?

SELECT m.briefmedialist, 
       Count(DISTINCT s.value) AS selected, 
       m.briefmedialistid 
FROM   vwmedialistmediachannels m 
       LEFT JOIN sessionfilters s 
              ON s.field = 'Media' 
                 AND m.briefmedialistid = s.value 
                 AND s.sessionid = @SessionID 
WHERE  m.id = (SELECT d.briefid 
               FROM   dashboards d 
               WHERE  d.dashboardguid IN (SELECT value 
                                          FROM   sessionfilters s 
                                          WHERE  s.sessionid = @SessionID 
                                                 AND s.field = 'DashboardID')) 
GROUP  BY m.briefmedialist, 
          m.briefmedialistid 
ORDER  BY m.briefmedialist 

2 个答案:

答案 0 :(得分:0)

您可以使用JOIN轻松替换子查询:

SELECT m.briefmedialist, 
       Count(DISTINCT s.value) AS selected, 
       m.briefmedialistid 
FROM   vwmedialistmediachannels m
    INNER JOIN dashboards d ON d.briefid = m.id
    INNER JOIN sessionfilters sd ON sd.VALUE = d.dashboardguid
    LEFT JOIN sessionfilters s  ON s.field = 'Media' 
                AND m.briefmedialistid = s.value 
                AND s.sessionid = @SessionID 
WHERE sd.sessionid = @SessionID 
   AND sd.field = 'DashboardID'
GROUP  BY m.briefmedialist, 
          m.briefmedialistid 
ORDER  BY m.briefmedialist 

不确定这是否会对性能有很大帮助,因为还有很多其他因素我们看不到 - 比如索引,表结构,列类型。另外,我猜,vwmedialistmediachannels是一个视图 - 所以无论它背后的是什么都会减慢查询速度。

答案 1 :(得分:0)

SELECT m.briefmedialist, 
       Count(DISTINCT d.dashboardguid) AS selected, 
       m.briefmedialistid 
  FROM vwmedialistmediachannels m 
  LEFT JOIN sessionfilters s 
    ON s.value = m.briefmedialistid 
   AND s.field = 'Media'
   AND s.sessionid = @SessionID
  JOIN dashboards d
    ON d.briefid = m.id 
  JOIN sessionfilters sf
    ON sf.Value = d.dashboardguid 
   AND sf.field = 'DashboardID'
   AND sf.sessionid = @SessionID
GROUP BY m.briefmedialist, 
         m.briefmedialistid 
ORDER BY m.briefmedialist

与Nenad类似,但将条件拉入连接有时可以让查询优化器尽早过滤

在查询优化器中查看。
有关于连接条件的索引 最后的尝试是尝试连接提示(合并,哈希,循环) 在复杂查询中,查询优化器不会评估连接选项,但我认为这不是这种情况 如果您看到所有循环连接,则尝试合并两个sessionfilters连接。

下一步是创建带有声明PK for

的#temp表
select distinct(s.value)
  from sessionfilters s 
 where s.field = 'Media'
   AND s.sessionid = @SessionID 

select distinct(sf.value)
  from sessionfilters sf
 where sf.sessionid = @SessionID 
   AND sf.field = 'DashboardID'