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

Откуда:
Сообщений: 6
Добрый день.
Не могу найти информацию как происходит хеширование при join.
Если на поле иметься индекс он будет хешировать его или не будет обращать внимание и начнет хешировать по таблице.
3 июн 21, 11:27    [22330807]     Ответить | Цитировать Сообщить модератору
 Re: Hash join, как работает хеширование с индексом.  [new]
Leonid Kudryavtsev
Member

Откуда:
Сообщений: 9664
Для join - индекс никак НЕ поможет
Для чтения/извлечения данных из таблицы - будет взят наиболее дешевый способ. Если в индексе есть все необходимые поля, то вместо извлечения данных из таблицы, возможно будет использоваться индекс.

IMHO & AFAIK
3 июн 21, 13:19    [22330873]     Ответить | Цитировать Сообщить модератору
 Re: Hash join, как работает хеширование с индексом.  [new]
Dimitry Sibiryakov
Member

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

hash join и индексы - вещь взаимоисключающая. Он применяется когда индексов нет или они
бесполезны.

Posted via ActualForum NNTP Server 1.5

3 июн 21, 13:24    [22330881]     Ответить | Цитировать Сообщить модератору
 Re: Hash join, как работает хеширование с индексом.  [new]
AmKad
Member

Откуда:
Сообщений: 5305
Dimitry Sibiryakov

hash join и индексы - вещь взаимоисключающая.
Неправда.
3 июн 21, 13:31    [22330887]     Ответить | Цитировать Сообщить модератору
 Re: Hash join, как работает хеширование с индексом.  [new]
Dimitry Sibiryakov
Member

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

AmKad
Неправда.

Ok. В каких случаях оптимизатор способен выбрать hash join с хэш-таблицей, созданной из
индекса, вместо merge join/nested loop c index scan?

Posted via ActualForum NNTP Server 1.5

3 июн 21, 13:38    [22330892]     Ответить | Цитировать Сообщить модератору
 Re: Hash join, как работает хеширование с индексом.  [new]
Gertf
Member

Откуда:
Сообщений: 6
Leonid Kudryavtsev,
В принципе я с вами согласен, но меня смущает что стоимость с 322к с индексом увеличивается до 36кк, при принудительном его выключении путем конкатенации доп символа при связывание.
3 июн 21, 13:43    [22330902]     Ответить | Цитировать Сообщить модератору
 Re: Hash join, как работает хеширование с индексом.  [new]
Gertf
Member

Откуда:
Сообщений: 6
быстрее всего звучит это хеширование изначений индекса, а не чтение всей таблицы.
3 июн 21, 13:45    [22330905]     Ответить | Цитировать Сообщить модератору
 Re: Hash join, как работает хеширование с индексом.  [new]
AmKad
Member

Откуда:
Сообщений: 5305
Dimitry Sibiryakov

Ok. В каких случаях оптимизатор способен выбрать hash join с хэш-таблицей, созданной из
индекса, вместо merge join/nested loop c index scan?
Leonid Kudryavtsev
Если в индексе есть все необходимые поля, то вместо извлечения данных из таблицы, возможно будет использоваться индекс.
+ для двух таблиц
drop table t1 purge;
drop table t2 purge;

create table t1 as
select 
rownum pk_id,
trunc(rownum / 100) fk_id,
dbms_random.string('p',  10) str_brief,
dbms_random.string('p', 100) str_long
from dual
connect by level <= 100000;

create table t2 as select * from t1;

create index t1#fk_id on t1(fk_id, pk_id, str_brief);

create index t2#fk_id on t2(fk_id, pk_id, str_brief);

explain plan for
select /*+ use_hash(t1 t2) */ t1.fk_id, t1.str_brief, t2.fk_id, t2.str_brief
from t1, t2
where t1.pk_id = t2.pk_id
and t1.fk_id = 100 and t2.fk_id = 100;

select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 980946122

------------------------------------------------------------------------------
| Id  | Operation         | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |          |   100 |  4000 |     4   (0)| 00:00:01 |
|*  1 |  HASH JOIN        |          |   100 |  4000 |     4   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN| T1#FK_ID |   100 |  2000 |     2   (0)| 00:00:01 |
|*  3 |   INDEX RANGE SCAN| T2#FK_ID |   100 |  2000 |     2   (0)| 00:00:01 |
------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("T1"."PK_ID"="T2"."PK_ID")
   2 - access("T1"."FK_ID"=100)
   3 - access("T2"."FK_ID"=100)

17 rows selected
+ для одной таблицы
drop table t3 purge;

create table t3 as 
select 
rownum id,
trunc(rownum / 1000) fk1_id,
mod  (rownum , 1000) fk2_id,
dbms_random.string('p',  10) str_brief,
dbms_random.string('p', 100) str_long
from dual
connect by level <= 100000;

create index t3#fk1_id on t3(fk1_id);
create index t3#fk2_id on t3(fk2_id);

explain plan for
select /*+ index_join(t3 t3#fk1_id t3#fk2_id) */ fk1_id, fk2_id
from t3
where fk1_id = 100 and fk2_id = 200;

select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 2358203619

--------------------------------------------------------------------------------
| Id  | Operation          | Name             | Rows  | Bytes | Cost (%CPU)| Tim
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |                  |     1 |     7 |     3   (0)| 00:
|*  1 |  VIEW              | index$_join$_001 |     1 |     7 |     3   (0)| 00:
|*  2 |   HASH JOIN        |                  |       |       |            |
|*  3 |    INDEX RANGE SCAN| T3#FK2_ID        |     1 |     7 |     1   (0)| 00:
|*  4 |    INDEX RANGE SCAN| T3#FK1_ID        |     1 |     7 |     2   (0)| 00:
--------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("FK2_ID"=200 AND "FK1_ID"=100)
   2 - access(ROWID=ROWID)
   3 - access("FK2_ID"=200)
   4 - access("FK1_ID"=100)

19 rows selected


Сообщение было отредактировано: 3 июн 21, 14:26
3 июн 21, 14:28    [22330923]     Ответить | Цитировать Сообщить модератору
 Re: Hash join, как работает хеширование с индексом.  [new]
Dimitry Sibiryakov
Member

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

А без искусственного форса метода?..

Posted via ActualForum NNTP Server 1.5

3 июн 21, 14:42    [22330929]     Ответить | Цитировать Сообщить модератору
 Re: Hash join, как работает хеширование с индексом.  [new]
AmKad
Member

Откуда:
Сообщений: 5305
Dimitry Sibiryakov

А без искусственного форса метода?..

alter system flush shared_pool;

drop table t5 purge;
drop table t6 purge;

create table t5 as
select 
rownum pk_id,
trunc(rownum / 100) fk_id,
dbms_random.string('p',  10) str_brief,
dbms_random.string('p', 100) str_long
from dual
connect by level <= 100000;

create table t6 as select * from t5;

create index t5#fk_id on t5(fk_id, pk_id, str_brief);

create index t6#fk_id on t6(fk_id, pk_id, str_brief);

explain plan for
select t5.fk_id, t5.str_brief, t6.fk_id, t6.str_brief
from t5, t6
where t5.pk_id = t6.pk_id
and t5.fk_id = 100 and t6.fk_id = 100;

select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 2200657797

------------------------------------------------------------------------------
| Id  | Operation         | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |          |   100 |  4000 |     4   (0)| 00:00:01 |
|*  1 |  HASH JOIN        |          |   100 |  4000 |     4   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN| T5#FK_ID |   100 |  2000 |     2   (0)| 00:00:01 |
|*  3 |   INDEX RANGE SCAN| T6#FK_ID |   100 |  2000 |     2   (0)| 00:00:01 |
------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("T5"."PK_ID"="T6"."PK_ID")
   2 - access("T5"."FK_ID"=100)
   3 - access("T6"."FK_ID"=100)

Note
-----

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
   - this is an adaptive plan

21 rows selected


alter system flush shared_pool;

drop table t4 purge;

create table t4 as 
select 
rownum id,
trunc(rownum / 1000) fk1_id,
mod  (rownum , 1000) fk2_id,
dbms_random.string('p',  10) str_brief,
dbms_random.string('p', 100) str_long
from dual
connect by level <= 100000;

create index t4#fk1_id on t4(fk1_id);
create index t4#fk2_id on t4(fk2_id);

explain plan for
select fk1_id, fk2_id
from t4
where fk1_id = 100 and fk2_id = 200;

select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 1544695100

--------------------------------------------------------------------------------
| Id  | Operation          | Name             | Rows  | Bytes | Cost (%CPU)| Tim
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |                  |     1 |     7 |     3   (0)| 00:
|*  1 |  VIEW              | index$_join$_001 |     1 |     7 |     3   (0)| 00:
|*  2 |   HASH JOIN        |                  |       |       |            |
|*  3 |    INDEX RANGE SCAN| T4#FK2_ID        |     1 |     7 |     1   (0)| 00:
|*  4 |    INDEX RANGE SCAN| T4#FK1_ID        |     1 |     7 |     2   (0)| 00:
--------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("FK2_ID"=200 AND "FK1_ID"=100)
   2 - access(ROWID=ROWID)
   3 - access("FK2_ID"=200)
   4 - access("FK1_ID"=100)

19 rows selected
3 июн 21, 15:02    [22330940]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить