Доброго времени суток!
FB 2.1.0.17176, 3-й диалект
Задача - выбрать все записи из главной таблицы и для каждой записи из
главной - одну запись с подчиненной, с минимальным id.
Разумеется, легче всего эта задача решается запросом
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
При попытке навязать MERGE-план потерпел неудачу
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+0
План остался таким же
PLAN JOIN (M NATURAL, JOIN (D1 D ORDER FK_DETAIL1_MASTER1, D2 D INDEX
(PK_DETAIL1)))
Что здесь не так?
P.S.
Скрипт
create table master1
(id integer not null);
alter table master1
add constraint pk_master1 primary key(id);
create table detail1
(id integer not null,
master_id integer not null);
alter table detail1
add constraint pk_detail1 primary key(id);
alter table detail1
add constraint fk_detail1_master1 foreign key(master_id) references
master1 (id);
commit;
insert into master1 values (1);
insert into master1 values (2);
insert into detail1 values (1,1);
insert into detail1 values (2,1);
insert into detail1 values (3,1);
insert into detail1 values (4,2);
insert into detail1 values (5,2);
insert into detail1 values (6,2);
insert into detail1 values (7,2);
commit;
С уважением, Евгений