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

dba.stackexchange https://dba.stackexchange.com/questions/11843

Вопрос

Мне нужно найти так называемую первую запись в базе данных для элементов, касающихся их партнеров. Я написал запрос, и он дает мне правильные результаты, но он отстой с выступлениями.
Я подозреваю, что пропустил зачатие, поэтому этот запрос может быть написан намного лучше. Поэтому я прошу вас помочь мне перепроектировать этот запрос, чтобы получить лучшую производительность.
Моя система базы данных - SQL Server 2008

declare @od_datuma datetime
declare @do_datuma datetime

set @od_datuma='2011-12-01'
set @do_datuma='2011-12-31'


select 
doc.PAR_ID
,sdo.art_id
,MIN(doc.id) as doc_id
from 
dokumenti
inner join DOC on dokumenti.tip=DOC.TIP
inner join SDO on DOC.ID=SDO.DOC_ID
left  outer join (
    select par_id,art_id from dokumenti
            inner join DOC on dokumenti.tip=DOC.TIP
            inner join SDO on DOC.ID=SDO.DOC_ID     
            where   dokumenti.NABAVA =1 and
                    dokumenti.KOL_UL=1 and
                    DOC.DATUM<@od_datuma
                )  as stari_uazi on DOC.PAR_ID=stari_uazi.PAR_ID and SDO.ART_ID=stari_uazi.ART_ID
where 
dokumenti.NABAVA =1 and
dokumenti.KOL_UL=1 and
stari_uazi.ART_ID is null and 
doc.datum between @od_datuma and @do_datuma
group by doc.PAR_ID,sdo.art_id
Это было полезно?

Решение

Первое, что я хотел бы добавить, где doc.datum> =@od_datuma и doc.datum <=@do_datuma, потому что имея предложение. Может быть, это даст намек на планировщик запросов. Тогда большой вопрос: почему внешнее соединение с подразделением? Значит ли «где .. star_uazi.art_id is null», что вы хотите исключить все ряды, возвращающиеся из подразделения? Я подозреваю, что подзадность является настоящим убийцей, потому что поиск DOC не ограничен (doc.datum <@od_datuma), поэтому он может принести огромное количество рядов, которые не имеют реальной цели, поскольку родительский запрос исключает эти ряды ...

Я предполагаю, что если вы подавите подзадность (левое внешнее соединение ...) у вас будет что -то очень близкое от того, что вы хотите, намного быстрее. Если вам нужно подавить некоторые строки из набора результатов, вы можете поместить их во временную таблицу и удалить их потом, это может быть быстрее, чем внешнее подкованное подзаконное соединение.

Обновление: Итак, если вы хотите сохранить только ряды между @od / @do _datum, удалите левое соединение и добавьте условие where DOC.DATUM between @od_ and @do_У вас будет такой же результат, и это будет намного быстрее.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с dba.stackexchange
scroll top