Кузнецов Евгений wrote:

select * from master1 m left join detail1 d1
     on d1.id = (select min(d2.id) from detail1 d2
                         where d2.master_id = m.id)

План
PLAN (D2 ORDER PK_DETAIL1 INDEX (FK_DETAIL1_MASTER1))
PLAN JOIN (M NATURAL, D1 INDEX (PK_DETAIL1))

На примере получаем 8 индексных чтений из detail1
и 2 неиндексных из master1

Ради интереса попробовал сделать через derived tables

select * from master1 m left join
((select min(d.id) id from detail1 d
 group by master_id) d1 inner join
  inner join detail1 d2
   on d1.id = d2.id)
on m.id = d2.master_id

План
PLAN JOIN (M NATURAL, JOIN (D1 D ORDER FK_DETAIL1_MASTER1, D2 D INDEX (PK_DETAIL1)))

Получаем 18 индексных чтений из detail1 и 2 неиндексных из master1 -

Планы разные.

т.е. запрос перевыполняется для каждой записи из master1

Он и в первом случае перевыполняется. Там же D1/D2 зависят от M.

При попытке навязать MERGE-план потерпел неудачу

Он не реализован для LEFT JOIN, я писал об этом.


--
Дмитрий Еманов

Ответить