Не так давно я опубликовал заметку о некотором варианте иерархического запроса, который выполняется очень долго (почти неограниченно) и не потребляет иных ресурсов базы данных кроме CPU.

Возникла довольно естественная идея использовать этот метод для сопоставления CPU интенсивных задач в БД Oracle. Например, если мы встраиваем такую прожорливую CPU-функцию в наш пайплайн исполнения SQL-запроса так, чтобы она выполнилась более миллиарда раз, то получаем возможность сравнить затраты на CPU в разных случаях.

В данном случае мы будем сравнивать по производительности различные функции хеширования в Oracle: ORA_HASH и различные варианты STANDARD_HASH.

Мы выполняем запросы следующего вида:

Baseline не выполняет доп. функций на CPU:

select * from (select distinct id
               from (select 'abcdef' id from dual
                     union all
                     select 'fgrjk' from dual)
               connect by level <= 3e1);

Запрос с ORA_HASH:

select * from (select distinct ora_hash(id,1111113)
               from (select 'abcdef' id from dual
                    union all
                    select 'fgrjk' from dual)
              connect by level <= 3e1);

Запрос с вычислением хеша одним из стандартных методов:

select * from (select distinct STANDARD_HASH(id,'SHA384') 
               from (select 'abcdef' id from dual 
                   union all 
                   select 'fgrjk' from dual) 
               connect by level <= 3e1);

Метод

Время исполнения (сек)

Разница с baseline на (%)

Baseline

773

0%

ORA_HASH

959

24.0%

MD5

1462

87.5%

SHA1

2536

228%

SHA256

5019

549%

SHA512

5061

554%

Типичный SQL Monitor-отчёт для подобных запросов:

SQL Monitoring Report
SQL Text
select * from (select distinct STANDARD_HASH(id,'SHA256') from (select 'abcdef' id from dual union all select 'fgrjk' from dual) connect by level <= 3e1)
Global Information
Status              :  DONE (ALL ROWS)
Instance ID         :  2
Session             :  REMIZOV (509:24232)
SQL ID              :  fwhbynu8jtfr3
SQL Execution ID    :  33554432
Execution Started   :  07/16/2024 10:11:47
First Refresh Time  :  07/16/2024 10:11:53
Last Refresh Time   :  07/16/2024 11:35:26
Duration            :  5019s
Module/Action       :  PL/SQL Developer/SQL Window
Service             :  ZZZZZZ
Program             :  plsqldev.exe
Fetch Calls         :  1
Global Stats
| Elapsed |   Cpu   |  Other   | Fetch |
| Time(s) | Time(s) | Waits(s) | Calls |
|    5019 |    4964 |       55 |     1 |
SQL Plan Monitoring Details (Plan Hash Value=682020348)
| Id |                 Operation                 | Name |  Rows   | Cost |   Time    | Start  | Execs |   Rows   |  Mem  | Activity | Activity Detail |
|    |                                           |      | (Estim) |      | Active(s) | Active |       | (Actual) | (Max) |   (%)    |   (# samples)   |
|  0 | SELECT STATEMENT                          |      |         |      |         1 |  +5019 |     1 |        2 |     . |          |                 |
|  1 |   VIEW                                    |      |       2 |    5 |         1 |  +5019 |     1 |        2 |     . |          |                 |
|  2 |    HASH UNIQUE                            |      |       2 |    5 |      5020 |     +0 |     1 |        2 | 507KB |    86.30 | Cpu (4327)      |
|  3 |     CONNECT BY WITHOUT FILTERING (UNIQUE) |      |         |      |      5014 |     +6 |     1 |       2G |  2048 |    13.70 | Cpu (687)       |
|  4 |      VIEW                                 |      |       2 |    4 |         1 |     +6 |     1 |        2 |     . |          |                 |
|  5 |       UNION-ALL                           |      |         |      |         1 |     +6 |     1 |        2 |     . |          |                 |
|  6 |        FAST DUAL                          |      |       1 |    2 |         1 |     +6 |     1 |        1 |     . |          |                 |
|  7 |        FAST DUAL                          |      |       1 |    2 |         1 |     +6 |     1 |        1 |     . |          |                 |
=======================================================================================================================================================

Выводы

Вычисление хеша методом MD5 в 3.5 раза более затратно, чем ORA_HASH, а также даёт добавку порядка 87% к общему времени выполнения запроса (baseline), что совсем неплохо.

Остальные методы вычисления стандартного хеша гораздо затратнее.

Комментарии (0)