Чем отличаются эти два sql-запроса?
они что, одинаковы до символа?
если вопрос в том, почему запросы, поступившие по разным каналам, по разному компилируются (и, соотв., выполняются то есть 2 пути:
- проверить, одинаковые ли соединения используются для передачи запросов (возможны всякие настройки, итпъ)
- смириться
с задачей "найти 10 отличий в запросах" не справился...ой
они что, одинаковы до символа?
я думал это сразу видно
в последних трех строчках связка по полю SYSTEM_ID идет по разным сущностям
как с хибернейтом справиться нашел кстати
щас все летает
инересно все таки идентичны запросы или нет....
ойПардон, не углядел...
я думал это сразу видно
в последних трех строчках связка по полю SYSTEM_ID идет по разным сущностям
как с хибернейтом справиться нашел кстатиКак справился?
щас все летает
инересно все таки идентичны запросы или нет....
Имо, запросы должны компилиться абсолютно одинаково.
select A.id, ...
from A left outer join B on A.a = B.a and A.b = B.b
where B.b = 1 and B.a = '315905723' or
B.b = 1 and B.c ='315905723' or
B.b = 1 and B.d ='315905723'
А вообще план запроса наводит на размышления, что вот так было бы быстрее.
Но это при условии что запросы идентичны (кажется да, но может что то упустил)
with B2 as
(select * from B where B.b = 1 and B.a = '315905723' or ...)
select A.id, ...
from A left outer join B2 on A.a = B2.a and A.b = B2.b
у меня крыша едет
select /*+ index(exerepenti0_ idx_texerep_ord)*/
exerepenti0_.orig_id as col_0_0_, exerepenti0_.system_id as col_0_1_, orderentit1_.orig_id as col_1_0_, orderentit1_.system_id as col_1_1_
from tExerep exerepenti0_
left outer join tOrder orderentit1_
on exerepenti0_.ORDER_ORIG_ID=orderentit1_.orig_id and exerepenti0_.SYSTEM_ID=orderentit1_.system_id
where
exerepenti0_.system_id=1 and exerepenti0_.ORDER_ORIG_ID='315905723'
select /*+ index(exerepenti0_ idx_texerep_ord)*/
exerepenti0_.orig_id as col_0_0_, exerepenti0_.system_id as col_0_1_, orderentit1_.orig_id as col_1_0_, orderentit1_.system_id as col_1_1_
from tExerep exerepenti0_
left outer join tOrder orderentit1_
on exerepenti0_.ORDER_ORIG_ID=orderentit1_.orig_id and exerepenti0_.SYSTEM_ID=orderentit1_.system_id
where
exerepenti0_.system_id=1 and exerepenti0_.ORDER_ORIG_ID='315905723'
or orderentit1_.system_id=1 and orderentit1_.ORIG_ID='315905723'
второй запрос отличается лишней строчкой в конце
у первого запроса кост 8
у второго - 314862
эти два запроса похоже все таки разные
изза внешнего джойна и ИЛИ в условии
первый запрос он делает INDEX RANGE SCAN по индексу внешнего ключа - все зашибись
второй запрос он делает INDEX FULL SCAN по этому же самому индексу
зачем FULL? не понимаю
пмойму надо делать тот же самый RANGE, а потом с мерджить или вернее с-ИЛИ-ить результы
кажется да, но может что то упустилмне уже кажется что не идентичны
второй запрос обязывает чтобы во второй таблице была запись
первый запрос же не обязывает
твой вариант с with тоже обязывает, т.е. он иддентич. второму запросу
outer вообще не пойму зачем.
select /*?*/ ...
from A left outer join B ...
where A.a = C1 and A.b = C2 or ...
нифига не идентично исходному, т.к. в первой таблицы могут быть строки, а во второй уже нет. Ну и думаю этим и объясняется что индекс не может быть взят не целиком.
по каким полям построен индекс IDX_TEXEREP_ORD?
статистика собрана?
по каким полям построен индекс IDX_TEXEREP_ORD?аккурат по внешнему ключу, т.е. system_id,order_orig_id
статистика собрана?
собсна в первом запросе хинт не нужен, индекс сам подхватывается
во втором без хинта - полный обход таблицы, с хинтом - полный обход индекса
я не умею статистику в оракле собирать...
select exerepenti0_.orig_id as col_0_0_, exerepenti0_.system_id as col_0_1_, orderentit1_.orig_id as col_1_0_, orderentit1_.system_id as col_1_1_
from tExerep exerepenti0_
left outer join tOrder orderentit1_
on exerepenti0_.ORDER_ORIG_ID=orderentit1_.orig_id and exerepenti0_.SYSTEM_ID=orderentit1_.system_id
where
exerepenti0_.system_id=1 and orderentit1_.ORIG_ID='315905723'
or exerepenti0_.system_id=1 and orderentit1_.parent_orig_id='315905723'
or exerepenti0_.system_id=1 and orderentit1_.root_orig_id='315905723'
select exerepenti0_.orig_id as col_0_0_, exerepenti0_.system_id as col_0_1_, orderentit1_.orig_id as col_1_0_, orderentit1_.system_id as col_1_1_
from tExerep exerepenti0_
left outer join tOrder orderentit1_
on exerepenti0_.ORDER_ORIG_ID=orderentit1_.orig_id and exerepenti0_.SYSTEM_ID=orderentit1_.system_id
where
orderentit1_.system_id=1 and orderentit1_.ORIG_ID='315905723'
or orderentit1_.system_id=1 and orderentit1_.parent_orig_id='315905723'
or orderentit1_.system_id=1 and orderentit1_.root_orig_id='315905723'
мб я торможу (и надо больше спать и позже приходить на работу )
но нафик там outer если по условию (where) поля во второй таблице не могут быть одновременно null ?
ЗЫ сорри, если сказал что-то очевидно верное или очевидно неверное- см. поправку из предыдущего поста
но нафик там outer если по условию (where) поля во второй таблице не могут быть одновременно null ?изначально было вот это:
where
exerepenti0_.system_id=1 and exerepenti0_.ORDER_ORIG_ID='315905723'
...
потому и аутер
постя сюда я это убрал чтоб не мешало наглядности
просто в схеме бд битые ссылки разрешены
щас я уже подумываю о том чтоб запретить битые ключи в селектах, ну тойсть чтобы такие сущности с бд вообще не возвращались
вернется второй разработчик с отпуска, обсудим...
те запросы что в начальном посте возврю одинаковые результаты - и теже результаты будут если убрать left outer ...
а на счет использования индексов все равно все в силе - если в OR'ах используются колонки разных таблиц то мвидимо оракл не осиливает, что можно индекс юзать
ЗЫ напиши полные запросы - только без этих убогих названий колонок и таблиц
напиши полные запросыи криейты на таблицы и индексы.
и криейты на таблицы
зачем?
там вроде всего 2-3 поля юзаются и один индекс
Судя по первому посту, индексов как минимум два.
первый запрос генерит hibernate и работает он намноооого дольше второгоА не надо использовать говно типа hibernate.
Все запросы надо писать руками и с пониманием.
Оставить комментарий
pitrik2
это внешние композитные ключи (по двум полям)первый запрос генерит hibernate и работает он намноооого дольше второго
вопрос, правильно ли я понимаю что запросы идентичны?
если правильно, то значит оракл туповат?
хоть я хинт и не подсуну hibernate-у, но все таки очень интересно, можно ли первый запрос подправить хинтами?
ну и самое сложное: как обуздать hibernate?
первый запрос
первый запрос
план первого:
план второго: