Order By и left Join

Запросы, планы, оптимизация запросов, ...

Модераторы: kdv, CyberMax

Ответить
_so_
Сообщения: 144
Зарегистрирован: 04 ноя 2004, 22:17

Order By и left Join

Сообщение _so_ » 02 май 2007, 16:11

Для примера есть две таблицы:

Код: Выделить всё

CREATE TABLE TABLE1 (
    ID  GUID NOT NULL /* GUID = INTEGER */
);
ALTER TABLE TABLE1 ADD CONSTRAINT PK_TABLE1 PRIMARY KEY (ID);
и
CREATE TABLE TABLE2 (
    ID  GUID NOT NULL /* GUID = INTEGER */
);
ALTER TABLE TABLE2 ADD CONSTRAINT PK_TABLE2 PRIMARY KEY (ID);
Вопрос такой является глюком для запроса:

Код: Выделить всё

select C.ID from Table1 C
left join Table2 A on A.ID=C.ID
Order By C.ID
такой план (для IB 7.5 и IB 2007):
PLAN SORT (JOIN (C NATURAL,A INDEX (RDB$PRIMARY3)))

Для запроса

Код: Выделить всё

select C.ID from Table1 C
join Table2 A on A.ID=C.ID
order by C.ID
План строится разумный:
PLAN JOIN (C ORDER RDB$PRIMARY2,A INDEX (RDB$PRIMARY3))
При этом для FB 2 план строится всегда нормальный.
При этом если запрос переделать в неявный left join, то план для Ib становится приемлемым:

Код: Выделить всё

select C.ID,  (select A.ID from Table2 A where  A.ID=C.ID) from Table1 C
order by C.ID
PLAN (A INDEX (PK_TABLE2)) PLAN (C ORDER PK_TABLE1)
Мне не совсем понятно почему если в запросе есть left join нельзя использовать индекс для сортировки. Является ли это глюком для Ib начиная с версии 7.5 или это тащится с раних версий IB, а в FB сделали по другому.

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 02 май 2007, 16:32

В Firebird уже многократно переписывался оптимизатор, так что даже в разных билдах FB он разный.
А уж от IB отличается, мягко говоря, существенно. По оптимизатору IB имхо тут специалистов нет, т.к. код коммерческий, и это у Борланда надо пытать.

_so_
Сообщения: 144
Зарегистрирован: 04 ноя 2004, 22:17

Сообщение _so_ » 02 май 2007, 17:32

Я понимаю, что они разные. Для разработчиков FB вопрос ипсравляли ли они этот код?

Я стал экспериментировать еще с FB2.0.1.12855
И нашел такую вещь если сделать запос:

Код: Выделить всё

select C.ID from Classes c
left join Abstract A on A.ID=C.ID
Order By C.ID
rows 10
То план запроса становится как и у IB
PLAN SORT (JOIN (C NATURAL, A INDEX (RDB$PRIMARY4)))
Если убрать left то все нормально.
Похоже если в FB что-то переделывали, то как-то не до конца.

dimitr
Разработчик Firebird
Сообщения: 888
Зарегистрирован: 26 окт 2004, 16:20

Сообщение dimitr » 02 май 2007, 23:04

тянется изначально. В FB исправлялось. Насчет ROWS - да, был наведенный баг. Исправлен в 2.1, если склероз не подводит...

_so_
Сообщения: 144
Зарегистрирован: 04 ноя 2004, 22:17

Сообщение _so_ » 03 май 2007, 10:02

dimitr писал(а):тянется изначально. В FB исправлялось. Насчет ROWS - да, был наведенный баг. Исправлен в 2.1, если склероз не подводит...
Да хреново. Для таблиц в которых большие данные и надо получить только n первых записей (которые выводятся на экран) использовать left join и сортировку нельзя (кроме версии FB 2.1).
И как интересно другие с этим боролись?

CyberMax
Заслуженный разработчик
Сообщения: 638
Зарегистрирован: 31 янв 2006, 09:05

Сообщение CyberMax » 03 май 2007, 10:10

_so_ писал(а):И как интересно другие с этим боролись?
Наверно, FIRST N юзали...

_so_
Сообщения: 144
Зарегистрирован: 04 ноя 2004, 22:17

Сообщение _so_ » 07 май 2007, 15:40

CyberMax писал(а): Наверно, FIRST N юзали...
Или LAST N ...

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 07 май 2007, 15:59

_so_ писал(а):Или LAST N ...
Нет такой. Но можно сымитировать.

Ответить