Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Оптимизация запроса / 11 сообщений из 11, страница 1 из 1
13.01.2018, 01:48
    #39583602
ДжонАутер
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
Поля во всех таблицах простого типа (number, varchar2(<200), date).
Статистика собрана.

Надо сгенерить новую таблицу на основе имеющихся данных:
1. Есть таблица порядка 80 полей и 2млн записей
2. К ней надо приаутерджойнить еще 10 таблиц в каждой порядка 100тыс записей
3. Каждая из этих 10 таблиц имеет > 15 полей, но приджойнить к большой таблиц надо только одной (то есть по одному полю джоин, другое идет в итоговый набор)
4. Джоин по намбер-полю и для каждой из 10 таблиц в исходной таблице свое поле для джоина

Просто ctas из исходной "большой" таблицы выполняется за 5сек.
Сделал к ней простой left outer join 10 таблиц
Для каждой из 10 таблиц сделал индексы, включающие необходимые поля для запроса (по два поля в индексе, план показывает, что в джоинах читаются только индексы).
Стало немного бодрее. Но:
- если отключить параллельное выполнение запрос выполняется 2мин, с параллельным - 1мин (имхо долго)
- план показывает что практически все джоины идут по NL + index range scan,
попробовал таблицы, которые побольше переписать на use_hash, - медленно 1.5мин даже в параллели.

Общий вопрос: есть ли вариант/метода эффективно саутерджойнить кучку таблиц к одной таблице?
...
Рейтинг: 0 / 0
13.01.2018, 07:41
    #39583618
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
ДжонАутер- если отключить параллельное выполнение запрос выполняется 2мин, с параллельным - 1мин (имхо долго)Чудак, сколько раз в час бизнесу нужно переливать все эти лямы из пустого в порожнее?
...
Рейтинг: 0 / 0
13.01.2018, 08:41
    #39583619
ДжонАутер
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
Elic , речь о небольшом куске данных, на которых отлаживаюсь.
Реально данных сотня млн записей и запрос отрабатвает час, что довольно долго на фоне остальных подобных запросов со сопоставимым объемом.
Что из пустого в порожнее, это однозначно, но с'est la vie )
...
Рейтинг: 0 / 0
13.01.2018, 09:39
    #39583622
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
ДжонАутерприджойнить к большой таблиц надо только одной (то есть по одному полю джоин, другое идет в итоговый набор)ДжонАутерОбщий вопрос: есть ли вариант/метода эффективно саутерджойнить кучку таблиц к одной таблице?Попробуй скаляры.
Но чтобы прочитать всё, нужно прочитать всё. И hash тут не помощник.
...
Рейтинг: 0 / 0
13.01.2018, 10:18
    #39583630
ДжонАутер
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
ElicПопробуй скаляры
Cудя по плану, в параллели практически это и делается (NL + index range scan), но попробую, спасибо )
...
Рейтинг: 0 / 0
13.01.2018, 10:33
    #39583634
ДжонАутер
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
ElicНо чтобы прочитать всё, нужно прочитать всё. И hash тут не помощник
Просто предполагаю, что сджойнить 2млн + 100тыс быстрее через IFFS + hash join buffered,
но при параллельном запросе выбирается почему-то NL + index range scan.

Но на самых простых тестовых данных выбирается-то именно IFFS + hash join, а тут что-то никак: если выключаешь параллель, то просто index fullscan (не iffs) + hash join, но работает медленнее чем NL IRS.
...
Рейтинг: 0 / 0
13.01.2018, 10:39
    #39583638
andreymx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
ДжонАутерElicНо чтобы прочитать всё, нужно прочитать всё. И hash тут не помощник
Просто предполагаю, что сджойнить 2млн + 100тыс быстрее через IFFS + hash join buffered,
но при параллельном запросе выбирается почему-то NL + index range scan.

Но на самых простых тестовых данных выбирается-то именно IFFS + hash join, а тут что-то никак: если выключаешь параллель, то просто index fullscan (не iffs) + hash join, но работает медленнее чем NL IRS.ресурсов ему хватает для IFFS + hash join на больших объемах?
...
Рейтинг: 0 / 0
13.01.2018, 11:26
    #39583641
ДжонАутер
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
andreymx, на упрощенном тестовом примере из двух таблиц сопоставимого объёма выбирается именно iffs + hash join
...
Рейтинг: 0 / 0
14.01.2018, 08:07
    #39583849
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
ДжонАутерandreymx, на упрощенном тестовом примере из двух таблиц сопоставимого объёма выбирается именно iffs + hash joinИ кто ведёт? Справочник? - Так это несопоставимый пример.
...
Рейтинг: 0 / 0
14.01.2018, 12:17
    #39583883
ДжонАутер
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
Почему справочник, ведет большая таблица:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
create table test_tab
as
select round(dbms_random.value(1, 100000)) as f1,
       round(dbms_random.value(1, 100)) as f2,
       round(dbms_random.value(1, 100)) as f3,       
       round(dbms_random.value(1, 100)) as f4       
  from dual connect by level < 3000001;
  
create table test_tab2 as select t.*, ROWNUM AS f5 from test_tab t where rownum < 1000001;
create index test_tab2_i on test_tab2(f5);

create table test_tab3 as select t.*, ROWNUM AS f5 from test_tab t where rownum < 1000001;
create index test_tab3_i on test_tab3(f5);

select /*+ no_parallel*/ t1.*, t2.f5, t3.f5
  from test_tab t1,
       test_tab2 t2,
       test_tab3 t3
 where t1.f1 = t2.f5(+)
   and t1.f1 = t3.f5(+);

-----------------------------------------------------------------------------------------
| Id  | Operation                | Name        | Rows    | Bytes     | Cost  | Time     |
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT         |             | 3100371 | 241828938 | 23546 | 00:04:43 |
| * 1 |   HASH JOIN RIGHT OUTER  |             | 3100371 | 241828938 | 23546 | 00:04:43 |
|   2 |    INDEX FAST FULL SCAN  | TEST_TAB3_I |  824834 |  10722842 |   624 | 00:00:08 |
| * 3 |    HASH JOIN RIGHT OUTER |             | 3100370 | 201524050 | 11911 | 00:02:23 |
|   4 |     INDEX FAST FULL SCAN | TEST_TAB2_I |  824834 |  10722842 |   624 | 00:00:08 |
|   5 |     TABLE ACCESS FULL    | TEST_TAB    | 3100368 | 161219136 |  1980 | 00:00:24 |
-----------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
------------------------------------------
* 1 - access("T1"."F1"="T3"."F5"(+))
* 3 - access("T1"."F1"="T2"."F5"(+))


По объему сопоставимо, по смыслу (примерно) то же.
При этом IFSS выбирается и когда включено параллельное выполнение.
...
Рейтинг: 0 / 0
18.01.2018, 07:49
    #39586175
ДжонАутер
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация запроса
Дело оказалось вот в чем.
Таблицы которые джойнятся патиционированы по списку.
Джойнил я одну патицию:
Код: plsql
1.
(select * from table_for_join where part = :part)


Где part - ключ секции. Надеясь на то, что он возьмет эту секцию и в ней будет IFFS по локальному индексу этой же секции, но не срабатывало выбирался NL + RS
Если же указать секцию явно
Код: plsql
1.
(select * from table_for_join partition(part))


То IFFS подхватывается нормально.
А если в локальный индекс добавить кроме нужных полей и ключ секции, то и с первым вариантом
Код: plsql
1.
(select * from table_for_join where part = :part)


как и ожидаешь, тоже выбирается IFFS + HASH JOIN.
В общем все решилось, наверняка это есть где-нибудь в документации, но не ищем легких путей )
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Оптимизация запроса / 11 сообщений из 11, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]