порядок джоинов в фб 1.5

все вопросы и ответы о среде для разработчиков от www.sqlly.com

Модераторы: kdv, Pavel Kutakov

Ответить
entryway
Сообщения: 71
Зарегистрирован: 13 апр 2006, 18:06

порядок джоинов в фб 1.5

Сообщение entryway » 05 мар 2007, 15:11

Всегда удивляло в фаирберде как каждый раз в запросах приходится "подбирать" порядок джоинов для быстрого выполнения. Причем на мой неопытный глаз именно "подбирать" - логику проследить сложно. Во всяком случае мне. То лефт джоины вверх вытягивать помогает (!?), то наоборот. Но сегодня и вовсе натолкнулся на смешной случай:

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

select ...
from infosms s
inner join sms_states on sms_states.id = s.state
left join operators o1 on o1.id = s.operator_id
left join operators o2 on o2.id = s.assigned_operator_id
inner join sms_services on sms_services.id = s.service_id
where (sms_states.doshow = 1) and (s.pendingstate = 0)
Запрос выполняется мгновенно (выбирается одна запись). Если переставить последний иннер на второе или первое место - запрос выполняется секунду. Но самое смешное дальше: если убить два лефт джоина, то уже никакой порядок оставшихся двух иннеров не будет выполнять запрос мгновенно. То есть просто добавление в запрос мусора вида:

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

left join operators o1 on o1.id = s.operator_id
left join operators o2 on o2.id = s.assigned_operator_id
ускорят запрос.

Что я делаю не так?

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 05 мар 2007, 15:26

объясните, пожалуйста:
в states могут быть состояния, которых нет в Operators, и их надо выбрать все? как в отношении s.operator_id, так и s.assigner_operator ?

статью www.ibase.ru/devinfo/joins.htm читали?

entryway
Сообщения: 71
Зарегистрирован: 13 апр 2006, 18:06

Сообщение entryway » 05 мар 2007, 15:44

Внимательно посмотрите запрос. Мне кажется вы попутали. s - это алиас на infosms, а не на sms_states. operator_id и assigned_operator_id естественно могут быть нулом, потому и лефт. В infosms нет записей со state которым нет соответствия в sms_states. В sms_states 5 записей, 3 из них с doshow == 1, две с 0.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 05 мар 2007, 15:54

ok. при left/right join таблицы обычно идут в плане так, как это указано в запросе. Поэтому желательно приводить не только запрос, но и план, также статистику запроса (время, reads, fetches - как минимум).

ответ понятен, но частично - в infosms есть записи, которым нет соответствия в operators по s.operator_id ? Грубо говоря, я хочу ясный ответ - Вы понимаете работу left join? Т.е. пишете их в запросе осознанно?
Примерно половина вопросов про left join - от "автоматизированных построителей" или непонимания.

p.s. поясняю. когда Вы пишете a left join b - в a выбираются все записи. Если "переставить последний иннер на второе или первое место" - вначале сервер выполнит совершенно другую работу, чем при перестановке таблиц. Чем больше записей выбираются таким способом - тем хуже время, например.

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Re: порядок джоинов в фб 1.5

Сообщение Merlin » 05 мар 2007, 15:55

entryway писал(а):Всегда удивляло в фаирберде как каждый раз в запросах приходится "подбирать" порядок джоинов для быстрого выполнения. Причем на мой неопытный глаз именно "подбирать" - логику проследить сложно.
Проще пареной репы. Иннер-объединения должны выполняться в такой последовательности, чтобы максимизировать усечение ими перебора длинных таблиц.
entryway писал(а): Во всяком случае мне. То лефт джоины вверх вытягивать помогает (!?), то наоборот.
Это из области "то их понюхает, то их полижет" (С). Лефт нужен там, где он нужен. Порядком иннер-объединений надо рулить при помощи хинтов +0 или секцией Plan.

entryway писал(а): то уже никакой порядок оставшихся двух иннеров не будет выполнять запрос мгновенно.
Под порядком иннеров понимаем порядок их записи собственными палчиками? Напрасно, напрасно... Порядок надо в плане запроса смотреть.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 05 мар 2007, 15:57

Под порядком иннеров понимаем порядок их записи
замечу, что я имел в виду порядок при left. про запрос с только inner я ничего не говорил :-) В любом случае план надо смотреть.

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

Re: порядок джоинов в фб 1.5

Сообщение dimitr » 05 мар 2007, 16:11

entryway писал(а):Что я делаю не так?
используешь 1.5?

entryway
Сообщения: 71
Зарегистрирован: 13 апр 2006, 18:06

Сообщение entryway » 05 мар 2007, 16:25

ответ понятен, но частично - в infosms есть записи, которым нет соответствия в operators по s.operator_id ?
да, в infosms бывают нулы.
Вы понимаете работу left join?
Разумеется.
Т.е. пишете их в запросе осознанно?
Ага.
Примерно половина вопросов про left join - от "автоматизированных построителей" или непонимания.
Я к ним не отношусь и построителей в глаза не видел.
Лефт нужен там, где он нужен
Вот пристали :) Он мне нужен! Именно там и так как я написал. И должен по логике быть внизу, после иннеров, так как ничего не отсекают. Но фича не в этом, фича в том, что если их убрать - время выполнения запроса увеличивается многократно. Считаю такое поведение - ошибкой в оптимизаторе, не иначе. Суть поста именно в этом. Надо бы проверить на 2.0. План в последнем случае такой: PLAN JOIN (S INDEX (INFOSMS_IDX8),SMS_STATES INDEX (PK_SMS_STATES,SMS_STATES_DOSHOW),SMS_SERVICES INDEX (PK_SMS_SERVICES)), где INFOSMS_IDX8 - индекс по pendingstate. Убиение индекса SMS_STATES_DOSHOW (созданного с утра в отчаянье) решило "проблему двух иннеров"

entryway
Сообщения: 71
Зарегистрирован: 13 апр 2006, 18:06

Re: порядок джоинов в фб 1.5

Сообщение entryway » 05 мар 2007, 16:29

dimitr писал(а):
entryway писал(а):Что я делаю не так?
используешь 1.5?
Да я практически уверен, что проблема именно в этом, но так как по глупости наплодил давным-давно кучу процедур в которых таблицы используются одновременно и по алиасу и по полному имени, то переход на 2.0 выглядит слегка проблематичным. Вот так и терплю до сих пор, блин.

Ответить