Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 Посоветуйте, какой вариант запроса выбрать  [new]
Humandra
Member

Откуда:
Сообщений: 64
Имею приличную, но не сверх большую таблицу TableDate - сейчас 0,5 миллиона записей, прирост примерно 100000 в год.
Имею два варианта запроса (упрощены, но на мой взгляд оставлена суть запросов), вроде бы возвращающие одно и то же:
1)
select  To_Date('01.03.2009', 'dd.mm.yyyy') - 1 T_Date -- дата
    , Dim -- некий разрез
    , sum(Sum_Table) T_Sum -- сумма
  from MyTable 
  where TableDate < To_Date('01.03.2009', 'dd.mm.yyyy')
  group by Dim
union all
select TableDate
    , Dim
    , sum(Sum_Table) T_Sum
  from MyTable 
  where TableDate between To_Date('01.03.2009', 'dd.mm.yyyy')  and To_Date('19.03.2009', 'dd.mm.yyyy')
  group by Dim, TableDate

2)
select case when TableDate < To_Date('01.03.2009', 'dd.mm.yyyy') - 1 then To_Date('01.03.2009', 'dd.mm.yyyy') - 1 else TableDate end T_Date
    , Dim
    , sum(Sum_Table) T_Sum
  from MyTable 
  where TableDate <= To_Date('19.03.2009', 'dd.mm.yyyy')
  group by Dim, case when TableDate < To_Date('01.03.2009', 'dd.mm.yyyy') - 1 then To_Date('01.03.2009', 'dd.mm.yyyy') - 1 else TableDate end  

По результату на живой базе - они практически эквивалентны по скорости (в рамках погрешности измерения - равны).
У таблицы есть два индекса - по дате и разрезу.
Признаться, я думала, что второй запрос будет быстрее - один скан по таблице, но это не так.
А на ваш взгляд, как лучше?
19 мар 09, 19:58    [6951720]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте, какой вариант запроса выбрать  [new]
Humandra
Member

Откуда:
Сообщений: 64
Да - план запроса в первом случае показывает, что индекс по дате используется (index range scan)
Во втором случае, конечно - table access full
19 мар 09, 20:03    [6951737]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте, какой вариант запроса выбрать  [new]
andreymx
Member

Откуда: Запорожье
Сообщений: 54398
Humandra

select  To_Date('01.03.2009', 'dd.mm.yyyy') - 1 T_Date -- дата
    , Dim -- некий разрез
    , sum(Sum_Table) T_Sum -- сумма
  from MyTable 
  where TableDate < To_Date('01.03.2009', 'dd.mm.yyyy') -- всё равно ведь full scan ?
  group by Dim
union all
select TableDate
    , Dim
    , sum(Sum_Table) T_Sum
  from MyTable 
  where TableDate between To_Date('01.03.2009', 'dd.mm.yyyy')  and To_Date('19.03.2009', 'dd.mm.yyyy')
  group by Dim, TableDate

2)
select case when TableDate < To_Date('01.03.2009', 'dd.mm.yyyy') - 1 then To_Date('01.03.2009', 'dd.mm.yyyy') - 1 else TableDate end T_Date
    , Dim
    , sum(Sum_Table) T_Sum
  from MyTable 
  where TableDate <= To_Date('19.03.2009', 'dd.mm.yyyy')
  group by Dim, case when TableDate < To_Date('01.03.2009', 'dd.mm.yyyy') - 1 then To_Date('01.03.2009', 'dd.mm.yyyy') - 1 else TableDate end  
19 мар 09, 20:24    [6951771]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте, какой вариант запроса выбрать  [new]
Humandra
Member

Откуда:
Сообщений: 64
Да - full scan - поэтому-то меня и удивляют результаты (то, что время выполнение практически одинаково), хотела получить объяснение...
Может разницу покрывает case в группировке?
19 мар 09, 20:30    [6951779]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте, какой вариант запроса выбрать  [new]
Humandra
Member

Откуда:
Сообщений: 64
А, черт - я невнимательный тормоз!
Все правильно, второй запрос быстрее.
Я просто тестировала на неодинаковых данных...
Извиняюсь, тогда вопрос закрыт...
19 мар 09, 20:35    [6951786]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте, какой вариант запроса выбрать  [new]
tim128
Member

Откуда:
Сообщений: 145
конечно 100тыс в год это копейки и задача в целом не ясна, но спортивного интереса ради - я бы суммировал данные поступившие за сутки ночью джобом в отдельную таблицу. И для описанного отчета получил бы не 100000*лет строк а на 2-3 порядка меньше. И IOT может избавить от full scan, хотя выйгрыша это модет и не дать
19 мар 09, 21:07    [6951835]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте, какой вариант запроса выбрать  [new]
mayton
Member

Откуда: loopback
Сообщений: 49831
Можно попробовать создать partitions по TableDate и subpartitions по Dim.
20 мар 09, 00:10    [6952124]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте, какой вариант запроса выбрать  [new]
Elic
Member

Откуда:
Сообщений: 29991
mayton
Можно попробовать создать partitions по TableDate и subpartitions по Dim.
На кой ляд?
20 мар 09, 08:24    [6952376]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте, какой вариант запроса выбрать  [new]
mayton
Member

Откуда: loopback
Сообщений: 49831
Elic
mayton
Можно попробовать создать partitions по TableDate и subpartitions по Dim.
На кой ляд?

Судя по постам ты - довольно крутой ораклоид, поэтому тебе объяснять не буду. Но если ты объяснишь автору преимущества и недостатки будет очень даже здорово. Если у автора таблица уже сегментирована то возьму своё предложение назад.
20 мар 09, 09:42    [6952625]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте, какой вариант запроса выбрать  [new]
AlexFF__|
Member

Откуда:
Сообщений: 2855
Судя по постам, он еще и понтовистый ораклоид ;)
20 мар 09, 09:55    [6952678]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте, какой вариант запроса выбрать  [new]
Вячеслав Любомудров
Member

Откуда: Владивосток
Сообщений: 18487
mayton
Судя по постам ты - довольно крутой ораклоид, поэтому тебе объяснять не буду.
А ты не ему объясни, а тому, кому советы даешь
Ведь на основании каких-то выводов ты вынес такое предложение, или просто слово красивое?
20 мар 09, 09:57    [6952689]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте, какой вариант запроса выбрать  [new]
mayton
Member

Откуда: loopback
Сообщений: 49831
ОК, Вячеслав. Вы правы.

2 Humandra

Стукните мне в аську.
20 мар 09, 10:02    [6952702]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте, какой вариант запроса выбрать  [new]
__vvp_
Member

Откуда: Санкт-Петербург
Сообщений: 1158
mayton
2 Humandra
Стукните мне в аську.

Хотелось бы здесь услышать
20 мар 09, 10:04    [6952719]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте, какой вариант запроса выбрать  [new]
Elic
Member

Откуда:
Сообщений: 29991
mayton
Судя по постам ты - довольно крутой ораклоид, поэтому тебе объяснять не буду.
Ляпнул - и в кусты?
20 мар 09, 10:08    [6952735]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте, какой вариант запроса выбрать  [new]
mayton
Member

Откуда: loopback
Сообщений: 49831


Я свои ошибки признаю! Было дело...
20 мар 09, 10:10    [6952742]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте, какой вариант запроса выбрать  [new]
Elic
Member

Откуда:
Сообщений: 29991
mayton
Я свои ошибки признаю!
Ждём-с...
20 мар 09, 10:20    [6952809]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте, какой вариант запроса выбрать  [new]
Humandra
Member

Откуда:
Сообщений: 64
Спасибо всем...
Насчет partitions - честно говоря, мне тоже не совсем понятно, зачем. В любом случае, его не позволяет сделать лицензия.

Вообще, вопрос производительности именно этого отчета серьезно не стоит, мне просто было интересно понять, почему то, что мне казалось очевидным, таковым не явилось.
Как выяснилось, очевидное таки является очевидным. :)

Вариант джоба с записью в группировочную таблицу рассматривался, но он трудно реализуем в силу очень частой и массовой изменяемости данных за прошлые периоды (такова бизнес логика, это не правка задним числом. Впрочем, неважно).
Да и пока результат получается в среднем на нужных условиях отбора секунд за 12 - этого вполне хватает.
20 мар 09, 20:15    [6956929]     Ответить | Цитировать Сообщить модератору
 Re: Посоветуйте, какой вариант запроса выбрать  [new]
гыгыгы
Guest
Humandra

select case when TableDate < To_Date('01.03.2009', 'dd.mm.yyyy') - 1 then To_Date('01.03.2009', 'dd.mm.yyyy') - 1 else TableDate end T_Date
    , Dim
    , sum(Sum_Table) T_Sum
  from MyTable 
  where TableDate <= To_Date('19.03.2009', 'dd.mm.yyyy')
  group by Dim, case when TableDate < To_Date('01.03.2009', 'dd.mm.yyyy') - 1 then To_Date('01.03.2009', 'dd.mm.yyyy') - 1 else TableDate end  


а почему бы не использовать вместо "case" - greatest(TableDate, To_Date('01.03.2009', 'dd.mm.yyyy')-1) ? Хотя производительность это не улучшит)
21 мар 09, 12:37    [6957756]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить