powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Интересно ваше мнение по поводу организации двух запросов
16 сообщений из 16, страница 1 из 1
Интересно ваше мнение по поводу организации двух запросов
    #39283879
Преамбула
Был запрос следующей структуры:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
select e.*,
       a.name_full aname
  from emplist e,
       agnlist a
    -- еще таблицы и внизу соединения с (+)
 where e.agnlist_rn = a.rn(+)
   and e.status = 'sdsd';


план:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
-----------------------------------------------------------------------------------------------
| Id  | Operation                      | Name                | Rows | Bytes | Cost | Time     |
-----------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |                     |    1 |   120 |    3 | 00:00:01 |
|   1 |   NESTED LOOPS OUTER           |                     |    1 |   120 |    3 | 00:00:01 |
|   2 |    TABLE ACCESS BY INDEX ROWID | EMPLIST             |    1 |    88 |    2 | 00:00:01 |
| * 3 |     INDEX RANGE SCAN           | EMPLIST_STATUS_IDX5 |    1 |       |    1 | 00:00:01 |
|   4 |    TABLE ACCESS BY INDEX ROWID | AGNLIST             |    1 |    32 |    1 | 00:00:01 |
| * 5 |     INDEX UNIQUE SCAN          | AGNLIST_PK          |    1 |       |    0 | 00:00:01 |
-----------------------------------------------------------------------------------------------


Можете на лефт джойны переписать в данном случае ничего не меняется... соединяемые поля индексированы и там и там...
Таблиц соединенных может быть много и все соединены через (+) и у всех используется на вывод по одному полю...

Без меня переписали следующем образом (был в ахуе от реализации, но перед тем как вести разборки проверил загрузку и план...)
Вариант как стало...
Код: plsql
1.
2.
3.
4.
5.
select e.*,
       (select a.name_full from agnlist a where a.rn = e.agnlist_rn) aname
       -- другие поля таким же образом...
  from emplist e
 where e.status = 'sdsd';



план:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
----------------------------------------------------------------------------------------------
| Id  | Operation                     | Name                | Rows | Bytes | Cost | Time     |
----------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT              |                     |    1 |    88 |    2 | 00:00:01 |
|   1 |   TABLE ACCESS BY INDEX ROWID | AGNLIST             |    1 |    32 |    2 | 00:00:01 |
| * 2 |    INDEX UNIQUE SCAN          | AGNLIST_PK          |    1 |       |    1 | 00:00:01 |
|   3 |   TABLE ACCESS BY INDEX ROWID | AGNLIST             |    1 |    27 |    2 | 00:00:01 |
| * 4 |    INDEX UNIQUE SCAN          | AGNLIST_PK          |    1 |       |    1 | 00:00:01 |
|   5 |   TABLE ACCESS BY INDEX ROWID | EMPLIST             |    1 |    88 |    2 | 00:00:01 |
| * 6 |    INDEX RANGE SCAN           | EMPLIST_STATUS_IDX5 |    1 |       |    1 | 00:00:01 |
----------------------------------------------------------------------------------------------


Cost стал меньше, байты тоже... в ASH нагрузка стала меньше... в разы...

Всегда ранее старался смотреть на соединение внизу... а не в выводе полей считая, что это лишние и лишнее...


Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
PL/SQL Release 11.2.0.3.0 - Production
CORE 11.2.0.3.0 Production
TNS for Linux: Version 11.2.0.3.0 - Production
NLSRTL Version 11.2.0.3.0 - Production
...
Рейтинг: 0 / 0
Интересно ваше мнение по поводу организации двух запросов
    #39283891
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Очумелый кроликнагрузка стала меньше... в разы...Не верю.
...
Рейтинг: 0 / 0
Интересно ваше мнение по поводу организации двух запросов
    #39283903
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ElicОчумелый кроликнагрузка стала меньше... в разы...Не верю.

потому что знаю количество строк в e
и распределение значений для пары (e.status, e.agnlist_rn) в его случае?
...
Рейтинг: 0 / 0
Интересно ваше мнение по поводу организации двух запросов
    #39283911
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
boobyпотому что знаюдва скаляра не должны быть эффективнее join-a
...
Рейтинг: 0 / 0
Интересно ваше мнение по поводу организации двух запросов
    #39283928
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
при малом значении

Код: plsql
1.
2.
3.
Select Count(distinct e.agnlist_rn)/Count( e.agnlist_rn)
From emplist e
where e.status = 'sdsd'



кэширование скаляров может быть интереснее явного соединения.

кроме того, отдельно, целесообразность индекса на e.status должна быть доказуема в конкретном случае.
Но пока эта не та история, которая удивляет топикстартера.
...
Рейтинг: 0 / 0
Интересно ваше мнение по поводу организации двух запросов
    #39283930
booby,

Хорошо...
Вариант с полным списком:

Код: plsql
1.
2.
3.
4.
5.
select e.*,
       a.name_full aname
  from emplist e,
       agnlist a
 where e.agnlist_rn = a.rn(+)



план:
-----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost | Time |
-----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 13671 | 1640520 | 1247 | 00:00:15 |
| * 1 | HASH JOIN OUTER | | 13671 | 1640520 | 1247 | 00:00:15 |
| 2 | TABLE ACCESS FULL | EMPLIST | 13671 | 1203048 | 68 | 00:00:01 |
| 3 | TABLE ACCESS FULL | AGNLIST | 146049 | 4673568 | 1178 | 00:00:15 |
-----------------------------------------------------------------------------


и

Код: plsql
1.
2.
3.
select e.*,
       (select a.name_full from agnlist a where a.rn = e.agnlist_rn) aname
  from emplist e



план
----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost | Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 13671 | 1203048 | 68 | 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID | AGNLIST | 1 | 32 | 2 | 00:00:01 |
| * 2 | INDEX UNIQUE SCAN | AGNLIST_PK | 1 | | 1 | 00:00:01 |
| 3 | TABLE ACCESS FULL | EMPLIST | 13671 | 1203048 | 68 | 00:00:01 |
----------------------------------------------------------------------------------------
...
Рейтинг: 0 / 0
Интересно ваше мнение по поводу организации двух запросов
    #39283935
booby,

что бы исключить статистические знания по количеству отбора строк в таблице E

1 вариант
Код: plsql
1.
2.
3.
4.
5.
6.
select e.*,
       a.name_full aname
  from emplist e,
       agnlist a
 where e.agnlist_rn = a.rn(+)
   and e.name_full like '%а%'



план:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
--------------------------------------------------------------------------------------
| Id  | Operation                      | Name       | Rows | Bytes | Cost | Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |            |  684 | 82080 |  753 | 00:00:10 |
|   1 |   NESTED LOOPS OUTER           |            |  684 | 82080 |  753 | 00:00:10 |
| * 2 |    TABLE ACCESS FULL           | EMPLIST    |  684 | 60192 |   68 | 00:00:01 |
|   3 |    TABLE ACCESS BY INDEX ROWID | AGNLIST    |    1 |    32 |    1 | 00:00:01 |
| * 4 |     INDEX UNIQUE SCAN          | AGNLIST_PK |    1 |       |    0 | 00:00:01 |
--------------------------------------------------------------------------------------


и второй вариант:
Код: plsql
1.
2.
3.
4.
select e.*,
       (select a.name_full from agnlist a where a.rn = e.agnlist_rn) aname
  from emplist e
 where e.name_full like '%а%'



план:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
-------------------------------------------------------------------------------------
| Id  | Operation                     | Name       | Rows | Bytes | Cost | Time     |
-------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT              |            |  684 | 60192 |   68 | 00:00:01 |
|   1 |   TABLE ACCESS BY INDEX ROWID | AGNLIST    |    1 |    32 |    2 | 00:00:01 |
| * 2 |    INDEX UNIQUE SCAN          | AGNLIST_PK |    1 |       |    1 | 00:00:01 |
| * 3 |   TABLE ACCESS FULL           | EMPLIST    |  684 | 60192 |   68 | 00:00:01 |
-------------------------------------------------------------------------------------
...
Рейтинг: 0 / 0
Интересно ваше мнение по поводу организации двух запросов
    #39283937
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Очумелый кролик,

хорошего здесь только то, что становится понятны размеры таблиц в штуках строк.

какого рода пояснений вы ждете к последним двум планам?
...
Рейтинг: 0 / 0
Интересно ваше мнение по поводу организации двух запросов
    #39283941
Elic,

Согласен... и говорю же что собирался устроить разборку, но начал проверять так как не люблю рубить с плеча...
и теперь я в таймауте и думаю почему!
...
Рейтинг: 0 / 0
Интересно ваше мнение по поводу организации двух запросов
    #39283945
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
boobyОчумелый кролик,

хорошего здесь только то, что становится понятны размеры таблиц в штуках строк.
какого рода пояснений вы ждете к последним двум планам?
то было два предпоследние.
а в последних что вас интересует?

попробуйте задать вопрос.
отвечать на мнение сорта "всегда думал" затруднительно, способом отличным от "иногда думай иначе".
...
Рейтинг: 0 / 0
Интересно ваше мнение по поводу организации двух запросов
    #39283961
Просто это выбило меня с моего мировоззрения, и хочу понять, может я от чего то сильно отстал и теперь вообще все не так?
Я как и Вы считал, что это должно работать медленнее... что это отдельные запросы на каждую строку и т.д.

Это пример соединений в реальности основная таблица имеет около 20 миллионов записей которые отбираются по ряду условий в средней выборке которых остается в пределах 1000 записей... иногда единицы записей, иногда сотни...
и есть порядка 10-15 таблиц расшифровки значений данных в основной таблице может не быть...

просто не пойму почему быстрее так как сам понимаю, что быть не должно...
...
Рейтинг: 0 / 0
Интересно ваше мнение по поводу организации двух запросов
    #39283968
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Очумелый кроликПросто это выбило меня с моего мировоззрения, и хочу понять, может я от чего то сильно отстал и теперь вообще все не так?
Я как и Вы считал, что это должно работать медленнее... что это отдельные запросы на каждую строку и т.д.

Это пример соединений в реальности основная таблица имеет около 20 миллионов записей которые отбираются по ряду условий в средней выборке которых остается в пределах 1000 записей... иногда единицы записей, иногда сотни...
и есть порядка 10-15 таблиц расшифровки значений данных в основной таблице может не быть...

просто не пойму почему быстрее так как сам понимаю, что быть не должно...

вы сферическими конями пытаетесь рассуждать.

Правильно ли предполагать, что "основной" вы называете emplist e?

авторЭто пример соединений в реальности основная таблица имеет около 20 миллионов записей которые отбираются по ряду условий в средней выборке которых остается в пределах 1000 записей... иногда единицы записей, иногда сотни...

вот этот "ряд условий" разделяется на три части в общем случае - какие-то из них работают
до соединения, какие-то фильтруют данный на фазе соединения, а какие-то остаются на потом - на последний фильтр после соединения.
Чем больше условий оказывается на последней фазе - тем хуже вашему соединению в смысле потраченных впустую усилий.
...
Рейтинг: 0 / 0
Интересно ваше мнение по поводу организации двух запросов
    #39283996
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Очумелый кроликпросто не пойму почему быстрее так как сам понимаю, что быть не должно...Буби же озвучил уже мысль про кеширование скаляров.
Код: plsql
1.
2.
3.
4.
create table t (id int primary key, name varchar2(30), padding varchar2(4000));
insert into t select rownum, 'name'||rownum, ' ' from dual connect by level <= 1e5;
update t set padding = lpad(' ', 4000, ' ');
commit;


Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
set timing on

select sum(length(name)) s
  from (select mod(rownum - 1, 5) + 1 id
          from (select rownum from dual
                union all
                select rownum from dual)
        connect by level < 23) x,
       t
 where x.id = t.id;

select sum(length((select name
                     from t
                    where x.id = t.id)))
          s
  from (select mod(rownum - 1, 5) + 1 id
          from (select rownum from dual
                union all
                select rownum from dual)
        connect by level < 23) x;


Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
         S
----------
  41943030
1 row selected.
Elapsed: 00:00:40.05

         S
----------
  41943030
1 row selected.
Elapsed: 00:00:13.72

В примере в три раза быстрее, если сделать доступ по rowid еще дороже, то можно воспроизвести чтоб было на порядок дольше и более.

PS. В ASH есть детали куда уходит время если что.
...
Рейтинг: 0 / 0
Интересно ваше мнение по поводу организации двух запросов
    #39284005
Фотография dbms_photoshop
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dbms_photoshopВ примере в три раза быстрее, если сделать доступ по rowid еще дороже, то можно воспроизвести чтоб было на порядок дольше и более.Доступ по rowid особой погоды не делает при небольшом числе distinct ключей соединения.
Конкуренцию по чтению еще можно организовать чтоб были всякие buffer busy waits/read by other session.
...
Рейтинг: 0 / 0
Интересно ваше мнение по поводу организации двух запросов
    #39284215
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Очумелый кролик,

решил добавить пару фраз к вышесказанному.

судя по характеру "подачи", у меня складывается впечатление, что вы ищете простое правило сорта - если у вас тут много, а там мало, то всегда делай соединение, а иначе всегда используй скалярный подзапрос.
Я думаю, одним-двумя ифами такого правила не сформулировать в том месте, в каком, например вы планируете такое правило применить для создания универсального представления, которым клиент (в отчетах, например) будет пользоваться для реализации
любой, наперед неизвестной потребности.

Пусть, применив вариант
Код: plsql
1.
2.
3.
4.
5.
select e.*,
       (select a.name_full from agnlist a where a.rn = e.agnlist_rn) aname
       -- другие поля таким же образом...
  from emplist e
 where e.status = 'sdsd';



где запрос возвращает тысячу-другую строк, и вы выиграли "в разы" в значениях интересных вам чиселок.
И даже все остается замечтательным при всех ранее известных вариантах фильтрации. и даже по полю aname.
Может быть, что "хорошо" может почти всегда, по крайней мере до тех пор, пока клиенту не понадобится
Код: plsql
1.
2.
3.
4.
5.
6.
7.
select e.*,
       (select a.name_full from agnlist a where a.rn = e.agnlist_rn) aname
       -- другие поля таким же образом...
  from emplist e
 where e.status = 'sdsd'
 Order By aname, -- другие поля таким же образом...
;


Никто не может вам гарантировать, что достигнутое вами "улучшение в разы" не сменится в этот момент "ухудшением в порядки раз".
...
Рейтинг: 0 / 0
Интересно ваше мнение по поводу организации двух запросов
    #39284287
Улучшение было не моим... Все что я хотел услышать - я услышал.
Ваше мнение совпадает с моим. Спасибо за ответы, так как хотел услышать мнение со стороны.

Тему закрываю.
...
Рейтинг: 0 / 0
16 сообщений из 16, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Интересно ваше мнение по поводу организации двух запросов
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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