ускорил запрос вот так, но есть ли решения по-приличнее?

ORAngutang
Дата: 26.11.2009 13:06:25
Всем привет! Разогнал такой запрос:

select ..., ...,  ...,
       ht.X, ht.Y, ht.Z,
       ..., ...,  ...
from MidlTable mt, HugeTable ht
where mt.id = ht.mt_id(+)      
  and mt.SomeFld = SomeValue   

следущим образом:

select ..., ...,  ...,
       ( select min( X ) from HugeTable where mt_id = mt.id ) as X
       ( select min( Y ) from HugeTable where mt_id = mt.id ) as Y
       ( select min( Z ) from HugeTable where mt_id = mt.id ) as Z   
       ..., ...,  ...
from MidlTable mt
 and mt.SomeFld = SomeValue          

Понятно, что если бы понадобилось не 3 поля, а много полей из HugeTable то такое бы не прокатило!
Разогнал таким методом примерно в 8 раз! (т.к. отпадает FullScan по HugeTable, которая значительно больше чем MidlTable )
Подозреваю, есть более элегантные решения...
____________________________________________________________
сейчас работаю на: Oracle 11.1.0.7.0, 64bit, standard edition, SLES-10. APEX 3.2
miksoft
Дата: 26.11.2009 13:10:15
А откуда там FullScan (для первоначального запроса), если вы сами говорите, что она "значительно больше чем MidlTable" ?

И, кстати, запросы не эквивалентны.
ORAngutang
Дата: 26.11.2009 13:41:14
miksoft
А откуда там FullScan (для первоначального запроса), если вы сами говорите, что она "значительно больше чем MidlTable" ?


на самом деле HugeTable это гигантская View (c многими UNION внутри) поэтому и FullScan


miksoft
И, кстати, запросы не эквивалентны.


как так!? А я даже тесты делал на сравнение возвращённых множеств!
( c "select from OldSql MINUS select from NewSql" )
Elic
Дата: 26.11.2009 13:46:15
ORAngutang
miksoft
И, кстати, запросы не эквивалентны.
как так!? А я даже тесты делал на сравнение возвращённых множеств!
Первый запрос возвращает >=count(mt.SomeFld = SomeValue), а второй =count(mt.SomeFld = SomeValue)
Вот так :)
suPPLer
Дата: 26.11.2009 13:46:32
ORAngutang,

неэквивалентность следует из отсутствующей информации, что одной записи в MidlTable всегда соответствует одна и только одна запись из HugeTable.
ORAngutang
Дата: 26.11.2009 14:18:08
suPPLer
одной записи в MidlTable всегда соответствует одна и только одна запись из HugeTable.


бааалин! сорьки! (посыпаю голову пеплом). Просто не выспался сегодня, и не указал эту особенность наших данных!
AlexFF__|
Дата: 26.11.2009 14:41:27
ORAngutang

Разогнал таким методом примерно в 8 раз! (т.к. отпадает FullScan по HugeTable, которая значительно больше чем MidlTable )
Подозреваю, есть более элегантные решения...


Сколь же вы экспериментировали, пока не нашли нормальное решение? ))
Почитайте про hint
ЗЫ стопудов нет индекса по внешнему ключу ;)
ORAngutang
Дата: 26.11.2009 17:32:31
AlexFF__|
Почитайте про hint

какой хинт мог бы подойти?

AlexFF__|
ЗЫ стопудов нет индекса по внешнему ключу ;)

там, как сказал, вьюха! И ключ этот в ней из разных кусков Union-ов строится (из разных таблиц!)

однко те две строчки что поставляет "плохой" (который с ".mt_id(+)") запрос (за 8 сек!) обе выбираются за доли секунды:

select min( Z ) from HugeTable where mt_id = "mt-id-1"

select min( Z ) from HugeTable where mt_id = "mt-id-2"
andrey_anonymous
Дата: 26.11.2009 17:41:51
ORAngutang
какой хинт мог бы подойти?

Мог бы подойти хинт index, разыменовывающий реальную таблицу через имя view
/*+ index(HugeVewAlias.BaseTableAliasInView RealIndexName)*/
ORAngutang
Дата: 26.11.2009 18:16:01
andrey_anonymous
ORAngutang
какой хинт мог бы подойти?

Мог бы подойти хинт index, разыменовывающий реальную таблицу через имя view
/*+ index(HugeVewAlias.BaseTableAliasInView RealIndexName)*/


Спасибо за идею, но нет! не соображает оракля что нужно брать этот индекс. :-(