2010-06-01 3 views
3

Возможно, есть очевидный ответ на этот вопрос, но у меня есть один момент времени, когда-либо с ним.Исключить записи, соответствующие подзапросу

Рассмотрим запрос:

 
SELECT * 
FROM reports AS r 
JOIN reportvalues AS rv ON rv.report_id = r.report_id 
JOIN metrics AS m ON m.metric_id = rv.metric_id 
WHERE r.report_id NOT IN(
    SELECT DISTINCT report_id 
    FROM exclude_report 
) 

В этом запросе exclude_report представляет собой вид строится аналогичным образом.

Теперь, что происходит, запрос выполняет ЧРЕЗВЫЧАЙНО долгое время, по-видимому, потому, что подзапрос выполняется по каждой строке в родительском запросе. Однако я не нахожу никаких возможных способов сделать это любым другим способом.

О, замечательные мастера SQL, пожалуйста, советую. Мне действительно нужен способ сделать все это в SQL, который я буду использовать в SSRS.

+0

Информация не достаточна. Просто запустите запрос в студии управления SQL-сервером и посмотрите план выполнения. Он покажет вам, какие аспекты медленны, и затем вы можете оптимизировать запрос на основе результатов. Всегда оптимизируйте факты, а не гипотезы. –

+0

Учитывая, что я парень MySQL, результат выполнения плана на самом деле не очень помогает мне. Каждый запрос индивидуально будет работать в считанные секунды, но все, что осталось на 5 минут, не завершено. Этап, на котором план исполнения показывает самую высокую стоимость, представляет собой «Сканирование с кластеризацией индексов» по ​​всем ПК, за которым следует «Hash Match». Я чувствую себя потерянным и смущенным. – Skudd

+0

Кстати, вам действительно нужен SELECT *? Или будет меньше столбцов? –

ответ

4

отчетливое, вероятно, убить вас, вам не нужно различны в подзапрос при использовании в

это лучше?

SELECT * 
FROM reports AS r 
JOIN reportvalues AS rv ON rv.report_id = r.report_id 
JOIN metrics AS m ON m.metric_id = rv.metric_id 
WHERE NOT EXISTS (SELECT 1 
     FROM exclude_report e 
     WHERE e.report_id = r.report_id) 
+0

Это выглядит довольно многообещающе. Просто на первый взгляд кажется, что он работает намного быстрее. – Skudd

+0

Perfect. Спасибо за помощь! – Skudd

0
SELECT * 
FROM reports AS r 
JOIN reportvalues AS rv ON rv.report_id = r.report_id 
JOIN metrics AS m ON m.metric_id = rv.metric_id 
LEFT JOIN exclude_report er ON r.report_id = er.report_id 
WHERE er.report_id IS NULL 
+0

Хммм, просто интересно, достаточно ли этого. Это не было бы наоборот ... –

+0

он мог бы получить несколько совпадений, но затем исключить их ... –

+0

Будет работать, но НЕ СУЩЕСТВУЕТ, более эффективен, так как он не извлекает строку из exclude_report. –

0

Вам не нужно отличное ключевое слово, которое может быть тяжелым. Я также советую вам добавлять индексы на внешние ключи больших таблиц.

+0

Отбрасывание 'DISTINCT', похоже, не имеет значения. – Skudd

0

Я думаю, что вы shold имеете следующие показатели:

  • поля report_id на столе report
  • поле report_id на столе reportvalues
  • поле metric_id на столе reportvalues
  • поле metric_id на столе metrics
  • Поле report_id на столе exclude_report
Смежные вопросы