2014-02-19 12 views
0
SELECT RC.Name AS RiskCategory, 
(SELECT 
     SUM(CASE WHEN IA.ImpactLevel = 'High' THEN 1 ELSE 0 END) 
     FROM 
     Rpt_ImpactAssess IA 
     JOIN 
     Rpt_Risk R 
     ON 
     IA.FKRiskID = R.RiskID 
     WHERE 
     R.RiskID IN 
     (
      SELECT FKRiskID  
      FROM 
      Rpt_Impact 
      WHERE FKItemID =38 
     ) 
     AND 
     R.RiskCatrogry = RC.Name   
    )AS High_Impact_Risks 

From RM_RiskCategories RC 
WHERE 
RC.Name <> 'All' 
GROUP BY 
RC.Name 
ORder By 
RC.Name DESC 
+0

Вы проверили план выполнения? Это определит, где настоящая проблема. Хотя я думаю, что повторная запись в соединение может немного улучшить производительность, SQL Server, как правило, довольно хорошо определяет, где коррелированный подзапрос может быть отпимирован в соединение. – GarethD

+0

Попросив людей попытаться оптимизировать запрос, отправьте свой текущий план выполнения и, если возможно, некоторые образцы данных. Мы не можем стрелять в темноте. – Rachcha

+0

Что говорят @GarethD и @RachCha, и есть ли какие-либо индексы на таблицах, которые вы используете? Почему во внешнем запросе есть «GROUP BY»? – NickyvV

ответ

1

Я довольно уверен, что это дает тот же результат, попробуйте:

SELECT RC.Name AS RiskCategory, 
     SUM(CASE WHEN IA.ImpactLevel = 'High' 
       THEN 1 
       ELSE 0 
      END) 
FROM RM_RiskCategories RC 
LEFT JOIN Rpt_Risk R ON R.RiskCatrogry = RC.Name 
LEFT JOIN Rpt_ImpactAssess IA ON IA.FKRiskID = R.RiskID 
WHERE RC.Name <> 'All' 
    AND (R.RiskID IS NULL 
    OR R.RiskID IN (SELECT FKRiskID  
        FROM Rpt_Impact 
        WHERE FKItemID = 38)) 
GROUP BY RC.Name 
ORDER BY RC.Name DESC 

Поскольку вам нужны все категории (точка я сначала пропустил) исходный запрос на самом деле может быть довольно хорошим способом сделать это - я действительно не поклонник использования LEFT JOIN ... WHERE pk IS NULL OR pk = something, как я должен был выше - так что вам определенно нужно проверить выше, чтобы увидеть, действительно ли это лучше.

Вы можете повернуть этот подзапрос в JOIN, но я не уверен, что будет какое-то увеличение производительности. Тем не менее, возможно, стоит тест, удалить подзапрос из пункта WHERE, и добавить еще LEFT JOIN:

LEFT JOIN Rpt_ImpactAssess IA ON IA.FKRiskID = R.RiskID 
WHERE ... AND (R.RiskID IS NULL OR RI.FKItemID = 38) 
+0

Привет, мне нужно получить все записи из RM_RiskCategories. INNER join возвращает только связанные категории, которые связаны в таблице риска. Но я должен показать все категории риска, которые связаны в таблице Rpt_Risk, или нет. –

+0

@ user3271821, извините, что полностью, обновил мой ответ. – OGHaza

+0

Yup now Это то, что я искал –

0

попробовать это, извините за синтаксисом, если any.it будет определенно быстрее, чем этот подзапрос .also попытаться создать соответствующие index.also зная это, что, в какой таблице возвращать сколько строк, когда присоединиться тогда, соответственно, вы можете разбить их в CTR.sometime это help.Also вы очень правильно использовать сумму вместо подсчета

SELECT RC.Name AS RiskCategory,SUM(CASE WHEN IA.ImpactLevel = 'High' THEN 1 ELSE 0 END)High_Impact_Risks 
From RM_RiskCategories RC 
inner join Rpt_Risk R on R.RiskCatrogry = RC.Name 
inner join Rpt_ImpactAssess IA on IA.FKRiskID = R.RiskID 
inner join dbo.Rpt_Impact R1 on R.RiskID=R1.FKRiskID and R1.FKItemID =38 
WHERE 
RC.Name <> 'All' 
GROUP BY 
RC.Name 
ORder By 
RC.Name DESC 
0

Проверьте, если это дает вы ожидаемый результат:

SELECT RC.Name AS RiskCategory, 
SUM(CASE WHEN IA.ImpactLevel = 'High' THEN 1 ELSE 0 END) AS High_Impact_Risks 
From RM_RiskCategories RC LEFT JOIN Rpt_Risk R 
ON R.RiskCatrogry = RC.Name 
INNER JOIN Rpt_ImpactAssess IA 
ON IA.FKRiskID = R.RiskID 
AND R.RiskID IN 
    (
     SELECT FKRiskID  
     FROM 
     Rpt_Impact 
     WHERE FKItemID =38 
    ) 
WHERE 
RC.Name <> 'All' 
GROUP BY 
RC.Name 
ORder By 
RC.Name DESC 

Некоторые дополнительные вещи, которые я хотел бы предложить вам проверить и добавить, если они не существуют, являются:

  1. Кластерный индекс Rpt_Impact (FKItemID)
  2. Кластерный индекс Rpt_Risk (RiskID)
  3. Кластерный индекс RM_RiskCategories (Имя)
  4. Non Индекс кластеризованную по Rpt_Risk (RiskCatrogry)
  5. Кластерный индекс Rpt_ImpactAccess (FKRiskID)
  6. Non Clustered index on Rpt_ImpactAccess (FKRiskID) INCLUDE (ImpactLevel)
0

Спасибо за вашу помощь и ответы. С вашей помощью я могу выяснить optemise мой запрос следующим образом:

ВЫБОР RC.Name AS RiskCategory, SUM (случай, когда IA.ImpactLevel = 'High' THEN 1 ELSE 0 END) AS High_Impact_Risks От RM_RiskCategories RC LEFT JOIN Rpt_Risk R ПО R.RiskCatrogry = RC.Name LEFT JOIN Rpt_ImpactAssess И.А. ПО IA.FKRiskID = R.RiskID И R.RiskID В ( ВЫБОР FKRiskID
ОТ Rpt_Impact ГДЕ FKItemID = 38 ) WHERE RC.Name <> 'Все' GROUP BY RC.Name Сортировать по RC.Name DESC