Страница 1 из 1
FB 2.5: параметр в where
Добавлено: 31 янв 2009, 12:43
VerLeon
Вот какую штуку обнаружил (заранее прошу прощения, если в трекере такое есть)
Выполняем запрос:
При любом значении параметра шерстится вся таблица. А зачем?
Собственно так было и в IB, и я к этому привык, как к неизбежному злу, но в FB я обнаружил вот что:
Код: Выделить всё
select * from rdb$database left join t1 on :param = 1
В IB разницы нет - все равно пройдет всю таблицу. В FB - ура! Если параметр не равен единице к t1 обращения не будет!
Значит оптимизатор это может все-таки обрабатывать? Но почему тогда в where не может?
Нет, я понимаю, что условия в on и условия в where - это разные вещи и обрабатываться должны по-разному, но в данном конкретном примере - какая разница?
В общем это не проблема, я таким джойнами теперь все и разруливаю, где мне надо, но ведь некрасиво и нелогично...
Re: FB 2.5: параметр в where
Добавлено: 02 фев 2009, 11:29
kdv
сначала строится план запроса, а только ПОТОМ - выполняется с полученными параметрами.
Т.е. на этапе построения плана сервер не знает, что будет в параметре. В FB 2.5 к исправлению подобных ситуаций были приняты меры, об этом надо смотреть в release notes по 2.5.
Статья о методах доступа - тут
www.ibase.ru/devinfo/dataaccesspaths.htm
Re: FB 2.5: параметр в where
Добавлено: 02 фев 2009, 12:43
VerLeon
Так я про планы и не говорю. Планы в части таблицы t1 будут одинаковыми (натуралы) в обоих случаях, что вполне понятно.
Отличаются эти запросы статистикой выполнения - в первом будут профетчены все записи из t1, во-втором при param <> 1 - ни одной.
Если я правильно понимаю механизм выполнения соединений, то во втором запросе будет применен алгоритм однопроходного слияния - должно строиться бинарное дерево слияния и при фетче анализироваться ключи. Но фетча из второго потока (t1) не происходит - хотя в первом потоке при любом значении параметра будет одна запись, он не будет пустой (прошу заметить, что условие во втором запросе стоит не в where, а именно в on). Значит сервер понял, что фетч бессмысленен (видимо после построения дерева слияния, которое по сути пустое получилось)? Т.е. при слиянии ПЕРЕД ФЕТЧЕМ такую проверку сделать можно и она реализована (за что большое спасибо). Но почему бы не сделать то же самое перед простым фетчем по where? Т.е. выделять предикаты, которые не зависят от фильтруемого потока из собственно фильтра и проверять их до фетча, а не после.
Еще раз повторю - я собственно и не настаиваю, особенно если это технически сложно реализовать, просто в итоге выглядят такие конструкции с джойнами странно и порождают вот такие вот вопросы (типа - на фига такие извращения?)
P.S. статью я читал, очень полезная статья
Re: FB 2.5: параметр в where
Добавлено: 02 фев 2009, 13:06
WildSery
VerLeon писал(а):P.S. статью я читал, очень полезная статья
Видимо, недостаточно хорошо, иначе бы не говорил об "однопроходном слиянии" в случае LEFT JOIN.
Re: FB 2.5: параметр в where
Добавлено: 02 фев 2009, 13:50
VerLeon
WildSery писал(а):Видимо, недостаточно хорошо, иначе бы не говорил об "однопроходном слиянии" в случае LEFT JOIN.
Да, ступил... Никогда раньше таких джойнов не делал, чтоб прицепляемая таблица не зависела от главной, посчитал в этом случае потоки независимыми

Но разве это что-то меняет?
Re: FB 2.5: параметр в where
Добавлено: 02 фев 2009, 21:56
WildSery
VerLeon писал(а):Но разве это что-то меняет?
Никто и не опровергает, что ты прав. Да, есть ещё куда развиваться оптимизатору
Хотя, такие ситуации "исправлять" нужно ИМХО в последнюю очередь - очень уж искусственный и надуманый запрос. Не буду гадать, почему везде применяешь, ведь легко заменяется на проверку+запрос в PSQL.