db file parallel read
Кроме recovery, операция используется при buffer prefetching [опережающем чтении блоков данных] как оптимизация I/O (заменяя несколько одноблочных чтений (single-block reads))
Показаны сообщения с ярлыком perfomance tuning. Показать все сообщения
Показаны сообщения с ярлыком perfomance tuning. Показать все сообщения
13 июля 2011 г.
oracle: log file switch
log file switch
Ожидание переключения лог файлов по причине незаконченной операции checkpoint – записи процессом DBWR модифицированных блоков бд из кэша (buffer cache) на диск
Ожидание переключения лог файлов по причине незаконченной операции checkpoint – записи процессом DBWR модифицированных блоков бд из кэша (buffer cache) на диск
oracle: log file switch completion
log file switch completion
Ожидание завершения процесса переключения лог файлов (online redo logs), вероятная причина – неправильный (малый) размер online лог файлов (redo logs), недостаточное количество групп лог файлов (redo log groups)
Ожидание завершения процесса переключения лог файлов (online redo logs), вероятная причина – неправильный (малый) размер online лог файлов (redo logs), недостаточное количество групп лог файлов (redo log groups)
oracle: log file sync
log file sync
Пользовательский сессия (foreground process) ожидает совершения системным процессом (background process) LGWR операции записи модифицированных данных из лог буфера в redo log файл во время выполнения пользовательской сессией операции завершения транзакции COMMIT / ROLLBACK.
Ожидание может быть заметно в случае низкой скорости записи процессом LGWR или высокой конкуренции за системные ресурсы (диск, процессор). Типичные причины: неудачное размещение и [коственно] малый размер лог файлов (online redo logs), низкая производительность и/или неудачная конфигурация подсистемы ввода-вывода*), либо высокая (возможно, избыточная?) интенсивность операций COMMIT / ROLLBACK**.
Нормальное время ожидания не должно превышать нескольких миллисекунд для OLTP систем
*) Пример: несколько копий лог файлов (для «надёжности») на одном небыстром разделе RAID5 либо RAID6 (для «экономии»). Время ожидания может легко превышать и 20, и 30, и 80 ms. Oracle категорически не рекомендует RAID5 для размещения online redo log файлов
**) При невозможности изменить приложение с целью уменьшить частоту транзакций, для буферизации и выбора асинхронного режима можно рассмотреть изменение параметров COMMIT_WRITE (начиная с Oracle 10g) или COMMIT_LOGGING, COMMIT_WAIT (начиная с 11g)
WAITEVENT: «log file sync» Reference Note [ID 34592.1]:
Ожидание log file sync может состоит из следующих компонент:
Пользовательский сессия (foreground process) ожидает совершения системным процессом (background process) LGWR операции записи модифицированных данных из лог буфера в redo log файл во время выполнения пользовательской сессией операции завершения транзакции COMMIT / ROLLBACK.
Ожидание может быть заметно в случае низкой скорости записи процессом LGWR или высокой конкуренции за системные ресурсы (диск, процессор). Типичные причины: неудачное размещение и [коственно] малый размер лог файлов (online redo logs), низкая производительность и/или неудачная конфигурация подсистемы ввода-вывода*), либо высокая (возможно, избыточная?) интенсивность операций COMMIT / ROLLBACK**.
Нормальное время ожидания не должно превышать нескольких миллисекунд для OLTP систем
*) Пример: несколько копий лог файлов (для «надёжности») на одном небыстром разделе RAID5 либо RAID6 (для «экономии»). Время ожидания может легко превышать и 20, и 30, и 80 ms. Oracle категорически не рекомендует RAID5 для размещения online redo log файлов
**) При невозможности изменить приложение с целью уменьшить частоту транзакций, для буферизации и выбора асинхронного режима можно рассмотреть изменение параметров COMMIT_WRITE (начиная с Oracle 10g) или COMMIT_LOGGING, COMMIT_WAIT (начиная с 11g)
WAITEVENT: «log file sync» Reference Note [ID 34592.1]:
Ожидание log file sync может состоит из следующих компонент:
1. сессия пользователя посылает вызов системному процессу LGWR, который начинает обработку запроса, если не занят обработкой др.вызовов
2. LGWR собирает/готовит необходимые для записи redo данные и вызывает операцию ввода/вывода
3. операция записи log write
4. обработка результатов записи процессом LGWR
5. LGWR посылает сообщение пользовательской сессии сообщение о выполнении операции записи
6. сессия пользователя продолжает работу
2. LGWR собирает/готовит необходимые для записи redo данные и вызывает операцию ввода/вывода
3. операция записи log write
4. обработка результатов записи процессом LGWR
5. LGWR посылает сообщение пользовательской сессии сообщение о выполнении операции записи
6. сессия пользователя продолжает работу
Шаги 2 и 3 суммируются в статистике redo write time
Шаг 3 соответствует системному событию ожидания (Background Wait Events) log file parallel write
Шаги 5 и 6 могут занимать значительное время при увеличенной системной загрузке (load average) … после посылки сообщения пользовательскому процессу о завершении выполнения операции, ОС может потребоваться время до очередного запуска пользовательского процесса на выполнение…
Шаг 3 соответствует системному событию ожидания (Background Wait Events) log file parallel write
Шаги 5 и 6 могут занимать значительное время при увеличенной системной загрузке (load average) … после посылки сообщения пользовательскому процессу о завершении выполнения операции, ОС может потребоваться время до очередного запуска пользовательского процесса на выполнение…
oracle: direct path write / direct path write temp
direct path write / direct path write temp
Ожидание выполнения операции записи (write call) возникает, когда пользовательский процесс пишет блоки данных данные напрямую (directly) из PGA (в отличие от DBWR, пишущего на диск из buffer cache).
Direct path writes выполняется при след.операциях: дисковые сортировки (direct path write temp), параллельные DML, direct-path INSERTs, параллельные create table as select и некоторые операции с LOB
Аналогично direct path reads, количество ожиданий не обязательно совпадает с кол-вом запросов на запись в асинхронном режиме»
Соответствующая ожиданию статистика physical write direct
Ожидание выполнения операции записи (write call) возникает, когда пользовательский процесс пишет блоки данных данные напрямую (directly) из PGA (в отличие от DBWR, пишущего на диск из buffer cache).
Direct path writes выполняется при след.операциях: дисковые сортировки (direct path write temp), параллельные DML, direct-path INSERTs, параллельные create table as select и некоторые операции с LOB
Аналогично direct path reads, количество ожиданий не обязательно совпадает с кол-вом запросов на запись в асинхронном режиме»
Соответствующая ожиданию статистика physical write direct
oracle: direct path read / direct path read temp
Источник: Oracle mechanics
direct path read / direct path read temp
«Возникает при чтении пользовательским процессом данных с диска напрямую в PGA (в отличие от чтения в buffer cache SGA)
В синхронном режиме ввода-вывода каждое ожидание соответствует запросу на физическое чтение. При использовании асинхронного ввода-вывода, [пользовательский] процесс Oracle способен совмещать генерацию запросов на чтение данных с обработкой блоков, уже находящихся в PGA. [И только] когда процесс пытается получить доступ к блоку, который ещё не был прочитан с диска в PGA, генерируется вызов (wait call) и обновляется статистика этого события. Таким образом, количество ожиданий не обязательно совпадает с кол-вом запросов на чтение (в отличие от ожиданий db file scattered read и db file sequential read)
Документ How does Oracle load data into the buffer cache for table scans ? [ID 787373.1] описывает правила выбора метода сканирования «больших» таблиц (или разделения таблиц на большие и маленькие - smallness logic):
Соответствующая ожиданию статистика physical reads direct
direct path read / direct path read temp
«Возникает при чтении пользовательским процессом данных с диска напрямую в PGA (в отличие от чтения в buffer cache SGA)
В синхронном режиме ввода-вывода каждое ожидание соответствует запросу на физическое чтение. При использовании асинхронного ввода-вывода, [пользовательский] процесс Oracle способен совмещать генерацию запросов на чтение данных с обработкой блоков, уже находящихся в PGA. [И только] когда процесс пытается получить доступ к блоку, который ещё не был прочитан с диска в PGA, генерируется вызов (wait call) и обновляется статистика этого события. Таким образом, количество ожиданий не обязательно совпадает с кол-вом запросов на чтение (в отличие от ожиданий db file scattered read и db file sequential read)
Типичные ситуации возникновения ожидания:
- Сортировка большого (по сравнению с размером PGA или sort_area_size) объёма данных, после записи во временный сегмент, данные считываются с использованием операций direct path read temp
- Использование параллельные процессами (parallel slaves)
- Пользовательский серверный процесс обрабатывает данные в PGA быстрее, чем система ввода-вывода может считывать очередные блоки данных (buffers). Может быть индикатором недостаточной производительности ввода-вывода»
Scattered Read, Sequential Read, and Direct Path Read
Операция direct path read применяется при непараллельном сканировании больших таблиц – см. High ‘direct path read’ waits in 11g [ID 793845.1]: «Начиная с Oracle 11g произошли изменения правил при выборе между операциями direct path reads и чтением через buffer cache (ожидание db file scattered read) при сканировании таблиц [full table scan].
В версии 10g, сканирование «больших» таблиц выполнялось через буферный кэш (по умолчанию). В 11g, решение о выполнении чтения данных с использованием direct path или через буферный кэш основывается на размере таблицы, размере буферного кэша и др.статистиках.
Direct path reads быстрее, чем scattered reads и меньше влияет на производительность др.процессов, т.к. исключает конкуренцию за latches
В версии 10g, сканирование «больших» таблиц выполнялось через буферный кэш (по умолчанию). В 11g, решение о выполнении чтения данных с использованием direct path или через буферный кэш основывается на размере таблицы, размере буферного кэша и др.статистиках.
Direct path reads быстрее, чем scattered reads и меньше влияет на производительность др.процессов, т.к. исключает конкуренцию за latches
Документ How does Oracle load data into the buffer cache for table scans ? [ID 787373.1] описывает правила выбора метода сканирования «больших» таблиц (или разделения таблиц на большие и маленькие - smallness logic):
- Если кол-во блоков меньше или равно параметру _small_table_threshold Oracle сканирует объект через buffer cache, считая это более эффективным, чем использование direct read
- Любой объект (таблица) размером менее 2% буферного кэша будет сканироваться через buffer cache без использования direct load
В блоге Alex’а Fatkulin 11G adaptive direct path reads — what is the cached/dirty blocks threshold? можно найти исследование некоторых параметров, которые берутся в расчёт Oracle при выборе использования direct path read:
- размер (в блоках) таблицы ~ _small_table_threshold умноженный на 5
- cached blocks threshold – кол-во блоков таблицы, уже находящихся в буферном кэше SGA
- dirty blocks threshold- кол-во изменённых блоков таблицы, находящихся в буферном кэше SGA, не сброшенных на диск процессом DBWR
imho, по умолчанию, при старте инстанса параметр _small_table_threshold устанавливается ~ 1.9-2 % от размера буферного кэша [__]db_cache_size / db_block_size
Для форсированного включения direct path read в документах поддержки упоминается установка параметра _serial_direct_read=TRUE (доступно на уровне сессии, значение по умолчанию FALSE)
Для отключения Dion Cho Disabling direct path read for the serial full table scan– 11g нашёл и описал событие 10949:
$ oerr 10949 "Disable autotune direct path read for full table scan" // *Cause: // *Action: Disable autotune direct path read for serial full table scan. //
SQL> alter session set events '10949 trace name context forever, level 1';
Соответствующая ожиданию статистика physical reads direct
oracle: read by other session
Сессия ожидает блок данных, который в настоящий момент считывается в буферный кэш (buffer cache) другой сессией. До версии 10g событие учитывалось в группе ожиданий buffer busy wait.
Может случаться, например, когда две сессии делают full table scan в одно и то же время.
Алгоритм:
- блок не найден в буферном кэше
- читаем блок с диска
- выясняем что другая сессия уже читает блок с диска
- ждём пока другая сессия закончит чтение
Может случаться, например, когда две сессии делают full table scan в одно и то же время.
Алгоритм:
- блок не найден в буферном кэше
- читаем блок с диска
- выясняем что другая сессия уже читает блок с диска
- ждём пока другая сессия закончит чтение
12 июля 2011 г.
oracle: Cartesian Joins
http://aguppi.blogspot.com/2011/07/oracle-table-joins.html
cbo-access-path
«… используется в случае, когда одна или несколько таблиц не имеют никаких условий (join conditions) для соединения с другими таблицами запроса. Оптимизатор соединяет каждую строку первого источника данных с каждой строкой другого, создавая картезианское произведение (Cartesian product) двух наборов данных»
cbo-access-path
«… используется в случае, когда одна или несколько таблиц не имеют никаких условий (join conditions) для соединения с другими таблицами запроса. Оптимизатор соединяет каждую строку первого источника данных с каждой строкой другого, создавая картезианское произведение (Cartesian product) двух наборов данных»
SQL> select job, dname from emp cross join dept; SQL> select job, dname from emp, dept; ----------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ----------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 56 | 1008 | 10 (0)| 00:00:01 | | 1 | MERGE JOIN CARTESIAN| | 56 | 1008 | 10 (0)| 00:00:01 | | 2 | TABLE ACCESS FULL | DEPT | 4 | 40 | 3 (0)| 00:00:01 | | 3 | BUFFER SORT | | 14 | 112 | 7 (0)| 00:00:01 | | 4 | TABLE ACCESS FULL | EMP | 14 | 112 | 2 (0)| 00:00:01 | ----------------------------------------------------------------------------- SQL> select /*+ ORDERED*/ * from dept d, bonus b, emp e 2 where d.deptno = e.deptno 3 and b.ename = e.ename; ------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 96 | 10 (10)| 00:00:01 | |* 1 | HASH JOIN | | 1 | 96 | 10 (10)| 00:00:01 | | 2 | MERGE JOIN CARTESIAN| | 1 | 59 | 6 (0)| 00:00:01 | | 3 | TABLE ACCESS FULL | DEPT | 4 | 80 | 3 (0)| 00:00:01 | | 4 | BUFFER SORT | | 1 | 39 | 3 (0)| 00:00:01 | | 5 | TABLE ACCESS FULL | BONUS | 1 | 39 | 1 (0)| 00:00:01 | | 6 | TABLE ACCESS FULL | EMP | 14 | 518 | 3 (0)| 00:00:01 | -------------------------------------------------------------------------------
В последнем примере благодаря подсказке ORDERED оптимизатор первым делом соединяет таблицы DEPT и BONUS, не имеющих по условиям запроса никаких условий для соединения (join keys), следовательно, единственной возможной операцией оказывается Join Cartesian.
В случае, когда две небольшие таблицы (DEPT и BONUS) соединяются через условия d.deptno = e.deptno and b.ename = e.ename к «большой» таблице EMP и имеются дополнительные условия на столбцы небольших таблиц (фильтры dept.loc = ‘CHICAGO’ and bonus.comm > 30), оптимизатор по соображениям избирательности (selectivity) без всяких подсказок выбирает Merge Join Cartesian небольших таблиц с последующим соединением (Hash join) с большой таблицей:
SQL> exec dbms_stats.set_table_stats(ownname => 'SCOTT',tabname => 'EMP', numrows => 100000);
PL/SQL procedure successfully completed.
SQL> select * from dept d, bonus b, emp e
2 where d.deptno = e.deptno and d.loc = 'CHICAGO'
3 and b.ename = e.ename and b.comm > 30;
Execution Plan
-------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2381 | 174K| 16 (44)| 00:00:01 |
|* 1 | HASH JOIN | | 2381 | 174K| 16 (44)| 00:00:01 |
| 2 | MERGE JOIN CARTESIAN| | 1 | 38 | 6 (0)| 00:00:01 |
|* 3 | TABLE ACCESS FULL | DEPT | 1 | 18 | 3 (0)| 00:00:01 |
| 4 | BUFFER SORT | | 1 | 20 | 3 (0)| 00:00:01 |
|* 5 | TABLE ACCESS FULL | BONUS | 1 | 20 | 3 (0)| 00:00:01 |
| 6 | TABLE ACCESS FULL | EMP | 100K| 3613K| 8 (63)| 00:00:01 |
-------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("D"."DEPTNO"="E"."DEPTNO" AND "B"."ENAME"="E"."ENAME")
3 - filter("D"."LOC"='CHICAGO')
5 - filter("B"."COMM">30)Хинты
Можно использовать ORDERED
oracle: Sort Merge Joins
http://aguppi.blogspot.com/2011/07/oracle-table-joins.html
Sort Merge Joins (Oracle docs)
cbo-access-path
Sort merge joins используются для объединения строк из 2х независимых таблиц.
Sort merge joins успешно используется, когда в условиях соединения двух таблиц присутствуют операторы сравнения: <, <=, >, или >= , но не для операторов равества/неравества. Производительность sort merge joins лучше, чем у nested loop joins для больших наборов данных (data sets). [Также следует обратить внимание на то, что ] вы не можете использовать [более производительные операции] hash joins для соединения таблиц, если условия соединения отличаются от равенства (equality condition).
Sort merge joins лучше Hash Joins если:
Например, при использовании оператора сравнения «>» несвязанных столцов видим по одной операции SORT JOIN для каждой таблицы и объединённую операцию MERGE JOIN:
SQL> select * from emp e, dept d where e.empno > d.deptno;
Execution Plan
В случае с отсортироваными значениями одна из операций SORT JOIN исключается за ненадобностью:
SQL> select * from
2 (select empno from emp order by 1) e,
3 (select deptno from dept order by 1) d
4 where e.empno > d.deptno;
Execution Plan
Хинты
/*+ USE_MERGE( tab1 tab2) */
Sort Merge Joins (Oracle docs)
cbo-access-path
Sort merge joins используются для объединения строк из 2х независимых таблиц.
Sort merge joins успешно используется, когда в условиях соединения двух таблиц присутствуют операторы сравнения: <, <=, >, или >= , но не для операторов равества/неравества. Производительность sort merge joins лучше, чем у nested loop joins для больших наборов данных (data sets). [Также следует обратить внимание на то, что ] вы не можете использовать [более производительные операции] hash joins для соединения таблиц, если условия соединения отличаются от равенства (equality condition).
Sort merge joins лучше Hash Joins если:
- строки уже отсортированы
- операция сортировки не должна выполняться
- Sort join: Оба источника входных данных / таблицы сортируются по ключу соединения (join key).
- Merge join: Совместная обработка / объдинение (merging) отсортированных списков.
Например, при использовании оператора сравнения «>» несвязанных столцов видим по одной операции SORT JOIN для каждой таблицы и объединённую операцию MERGE JOIN:
SQL> select * from emp e, dept d where e.empno > d.deptno;
Execution Plan
----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 56 | 3192 | 6 (17)| 00:00:01 |
| 1 | MERGE JOIN | | 56 | 3192 | 6 (17)| 00:00:01 |
| 2 | SORT JOIN | | 14 | 518 | 2 (0)| 00:00:01 |
| 3 | TABLE ACCESS BY INDEX ROWID| EMP | 14 | 518 | 2 (0)| 00:00:01 |
| 4 | INDEX FULL SCAN | PK_EMP | 14 | | 1 (0)| 00:00:01 |
|* 5 | SORT JOIN | | 4 | 80 | 4 (25)| 00:00:01 |
| 6 | TABLE ACCESS FULL | DEPT | 4 | 80 | 3 (0)| 00:00:01 |
----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
5 - access(INTERNAL_FUNCTION("E"."EMPNO")>INTERNAL_FUNCTION("D"."DEPTNO"))
filter(INTERNAL_FUNCTION("E"."EMPNO")>INTERNAL_FUNCTION("D"."DEPTNO"))В случае с отсортироваными значениями одна из операций SORT JOIN исключается за ненадобностью:
SQL> select * from
2 (select empno from emp order by 1) e,
3 (select deptno from dept order by 1) d
4 where e.empno > d.deptno;
Execution Plan
------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 56 | 896 | 3 (34)| 00:00:01 |
| 1 | MERGE JOIN | | 56 | 896 | 3 (34)| 00:00:01 |
| 2 | INDEX FULL SCAN | PK_DEPT | 4 | 12 | 1 (0)| 00:00:01 |
|* 3 | SORT JOIN | | 14 | 182 | 2 (50)| 00:00:01 |
| 4 | VIEW | | 14 | 182 | 1 (0)| 00:00:01 |
| 5 | INDEX FULL SCAN| PK_EMP | 14 | 56 | 1 (0)| 00:00:01 |
------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("E"."EMPNO">"DEPTNO")
filter("E"."EMPNO">"DEPTNO")Хинты
/*+ USE_MERGE( tab1 tab2) */
11 июля 2011 г.
oracle: hash Joins
http://aguppi.blogspot.com/2011/07/oracle-table-joins.html
Hash Joins (Oracle docs)
Hash Joins используются для объединения больших наборов данных.
Оптимизатор выбирает меньшую таблицу и создает хеш-таблицу для ключа объединения в памяти. Затем он просматривает другую таблицу(большую) и проверяет хеш таблицу в памяти на совпадения с ней.
Hash Join Hint
/*+ USE_HASH(tab1 tab2)*/
Hash Joins (Oracle docs)
Hash Joins используются для объединения больших наборов данных.
Оптимизатор выбирает меньшую таблицу и создает хеш-таблицу для ключа объединения в памяти. Затем он просматривает другую таблицу(большую) и проверяет хеш таблицу в памяти на совпадения с ней.
Hash Join Hint
/*+ USE_HASH(tab1 tab2)*/
SELECT /*+use_hash(employees departments)*/ * FROM employees, departments WHERE employees.department_id = departments.department_id;
8 июля 2011 г.
oracle: Nested Loop Joins
http://aguppi.blogspot.com/2011/07/oracle-table-joins.html
Nested Loop Joins (Oracle docs)
Nested Loops (объединения с вложенными циклами) - читает строку из 1й таблицы(ведущая таблица - outer table), и затем сравнивает всю 2ю таблицу(ведомая таблица - inner table) на совпадение, затем берёт следующую строку из 1й таблицы и опять сравнивает всю 2ю таблицу на совпадение и т.д.
Nested Loops hint
Используем хинт /*+ USE_NL*/, можно в связке с ORDERED, чтобы гарантировать нужный порядок обращения к таблицам.
Nested Loops быстро извлекают 1е несколько строк результирующего множества, но по общему времени выполнения Hash Joins быстрее. Этим свойством можно воспользоваться, когда пользователю нужно быстро получить 1е несколько строк, не дожидаясь всего результата.
В плане выполнения сначала идёт цикл по 1й таблице(outer loop) , а потом по 2й (inner loop)
В этом примере outer loop сначала получает все строки из таблицы EMPLOYEES, а затем для каждого сотрудника inner loop получает соответствующие строки из таблицы JOBS.
Nested Loops идеален, если 1я таблица маленькая, и объединённые столбцы проиндексированы уникально или этот индекс высоко избирательный.
Строка из 1й таблицы обычно получается из index scan или full table scan, а из 2й таблицы было бы идеально, чтобы строка выбиралась с помощью index scan.
Nested Loop Joins (Oracle docs)
Nested Loops (объединения с вложенными циклами) - читает строку из 1й таблицы(ведущая таблица - outer table), и затем сравнивает всю 2ю таблицу(ведомая таблица - inner table) на совпадение, затем берёт следующую строку из 1й таблицы и опять сравнивает всю 2ю таблицу на совпадение и т.д.
Nested Loops hint
Используем хинт /*+ USE_NL*/, можно в связке с ORDERED, чтобы гарантировать нужный порядок обращения к таблицам.
SELECT /*+ ORDERED USE_NL(customers) to get first row faster */ accounts.balance, customers.last_name, customers.first_name FROM accounts, customers WHERE accounts.customer_id = customers.customer_id;
SELECT /*+ USE_NL(l h) */ h.customer_id, l.unit_price * l.quantity FROM orders h ,order_items l WHERE l.order_id = h.order_id;
Nested Loops быстро извлекают 1е несколько строк результирующего множества, но по общему времени выполнения Hash Joins быстрее. Этим свойством можно воспользоваться, когда пользователю нужно быстро получить 1е несколько строк, не дожидаясь всего результата.
В плане выполнения сначала идёт цикл по 1й таблице(outer loop) , а потом по 2й (inner loop)
NESTED LOOPSouter_loopinner_loop
...
| 2 | NESTED LOOPS | | 3 | 141 | 7 (15)|
|* 3 | TABLE ACCESS FULL | EMPLOYEES | 3 | 60 | 4 (25)|
| 4 | TABLE ACCESS BY INDEX ROWID| JOBS | 19 | 513 | 2 (50)|
|* 5 | INDEX UNIQUE SCAN | JOB_ID_PK | 1 | | |
... В этом примере outer loop сначала получает все строки из таблицы EMPLOYEES, а затем для каждого сотрудника inner loop получает соответствующие строки из таблицы JOBS.
Nested Loops идеален, если 1я таблица маленькая, и объединённые столбцы проиндексированы уникально или этот индекс высоко избирательный.
Строка из 1й таблицы обычно получается из index scan или full table scan, а из 2й таблицы было бы идеально, чтобы строка выбиралась с помощью index scan.
oracle: Избирательность индекса
В представлении USER_INDEXES есть столбец distinct_keys, который содержит кол-во уникальных ключей для этого индекса. Сравнение distinct_keys и числа строк в таблице позволяет определить избирательность индекса. Чем ближе distinct_keys к числу строк в таблице, тем более избирательный индекс, запрос с использованием этого индекса вернёт меньшее кол-во строк, сообтветсвенно быстрее отработает запрос. Но при использовании дополнительных индексов (сложные/сцепленные индексы) в запросе издержки могут превысить выгоду.
5 июля 2011 г.
oracle: Tables Joins (объединения таблиц)
Из Oracle9i Database Performance Tuning Guide and Reference Release 2 (9.2) Understanding Joins
CBO access path
Виды соединений:
Nested Loop Joins
Hash Joins
Sort Merge Joins
Cartesian Joins
Outer Joins
Как оптимизатор выбирает метод соединения
Оптимизатор оценивает стоимость каждого метода и выбирает самый дешёвый из них.
Как оптимизатор выбирает Execution Plan (план выполнения)
Оптимизатор должен решить в каком порядке соединять таблицы, т.е. какая таблица будет 1й, 2й и т.д.
Если нужно указать порядок соединения вручную, то используется хинт ORDERED (/*+ ORDERED */), тогда соединение осуществляется в том порядке, в котором указаны таблицы после from.
Например: select /*+ ORDERED*/ col1, col2, col3, col4 from t1, t2, t3
Это одинаково для CBO и RBO:
CBO access path
Виды соединений:
Nested Loop Joins
Hash Joins
Sort Merge Joins
Cartesian Joins
Outer Joins
Как оптимизатор выбирает метод соединения
Оптимизатор оценивает стоимость каждого метода и выбирает самый дешёвый из них.
- Nested Loop Joins обычно не эффективен при соединении большого кол-ва строк (обычно более 10 000 строк уже много). Стоимость Nested Loop Joins рассчитывается по формуле:
cost= access cost of A + (access cost of B * number of rows from A)
- Hash Joins эффективны для большого кол-ва строк. Стоимость Hash Joins рассчитывается по формуле:
cost= (access cost of A * number of hash partitions of B) + access cost of B
- При использовании RBO оптимизатора эффективны Merge Joins. Стоимость Merge Joins рассчитывается по формуле:
cost= access cost of A + access cost of B +(sort cost of A + sort cost of B)
Если данные уже отсортированы, то стоимость сортировки равна нулю.
Как оптимизатор выбирает Execution Plan (план выполнения)
Оптимизатор должен решить в каком порядке соединять таблицы, т.е. какая таблица будет 1й, 2й и т.д.
Если нужно указать порядок соединения вручную, то используется хинт ORDERED (/*+ ORDERED */), тогда соединение осуществляется в том порядке, в котором указаны таблицы после from.
Например: select /*+ ORDERED*/ col1, col2, col3, col4 from t1, t2, t3
Это одинаково для CBO и RBO:
- Оптимизатор определяет какая из таблиц вернёт не более чем одну строку основываясь на ограничениях
UNIQUEиPRIMARYKEYдля таблицы. Если такая ситуация действительна, то оптимизатор ставит эту таблицу на первое место в соединении - For join statements with outer join conditions, the table with the outer join operator must come after the other table in the condition in the join order. The optimizer does not consider join orders that violate this rule.
With the CBO, the optimizer generates a set of execution plans, according to possible join orders, join methods, and available access paths. The optimizer then estimates the cost of each plan and chooses the one with the lowest cost. The optimizer estimates costs in the following ways:
- The cost of a nested loops operation is based on the cost of reading each selected row of the outer table and each of its matching rows of the inner table into memory. The optimizer estimates these costs using the statistics in the data dictionary.
- The cost of a sort merge join is based largely on the cost of reading all the sources into memory and sorting them.
oracle: Sample Table Scans
http://aguppi.blogspot.com/2011/06/oracle-access-path.html
A sample table scan retrieves a random sample of data from a table. This access path is used when a statement's
FROM clause includes the SAMPLE clause or the SAMPLE BLOCK clause. To perform a sample table scan when sampling by rows (the SAMPLE clause), Oracle reads a specified percentage of rows in the table. To perform a sample table scan when sampling by blocks (the SAMPLE BLOCK clause), Oracle reads a specified percentage of table blocks.Oracle does not support sample table scans when the query involves a join or a remote table. However, you can perform an equivalent operation by using a
CREATE TABLE AS SELECT query to materialize a sample of an underlying table. You then rewrite the original query to refer to the newly created table sample. Additional queries can be written to materialize samples for other tables. Sample table scans require the CBO.Example 1-13 uses a sample table scan to access 1% of the
employees table, sampling by blocks.Example 1-13 Sample Table Scan
SELECT * FROM employees SAMPLE BLOCK (1);
The
EXPLAIN PLAN output for this statement might look like this:------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| ------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 68 | 3 (34)| | 1 | TABLE ACCESS SAMPLE | EMPLOYEES | 1 | 68 | 3 (34)| -------------------------------------------------------------------------
oracle: Hash Scans
http://aguppi.blogspot.com/2011/06/oracle-access-path.html
A hash scan is used to locate rows in a hash cluster, based on a hash value. In a hash cluster, all rows with the same hash value are stored in the same data block. To perform a hash scan, Oracle first obtains the hash value by applying a hash function to a cluster key value specified by the statement. Oracle then scans the data blocks containing rows with that hash value.
A hash scan is used to locate rows in a hash cluster, based on a hash value. In a hash cluster, all rows with the same hash value are stored in the same data block. To perform a hash scan, Oracle first obtains the hash value by applying a hash function to a cluster key value specified by the statement. Oracle then scans the data blocks containing rows with that hash value.
oracle: Cluster Scans
http://aguppi.blogspot.com/2011/06/oracle-access-path.html
A cluster scan is used to retrieve, from a table stored in an indexed cluster, all rows that have the same cluster key value. In an indexed cluster, all rows with the same cluster key value are stored in the same data block. To perform a cluster scan, Oracle first obtains the rowid of one of the selected rows by scanning the cluster index. Oracle then locates the rows based on this rowid.
A cluster scan is used to retrieve, from a table stored in an indexed cluster, all rows that have the same cluster key value. In an indexed cluster, all rows with the same cluster key value are stored in the same data block. To perform a cluster scan, Oracle first obtains the rowid of one of the selected rows by scanning the cluster index. Oracle then locates the rows based on this rowid.
9 июня 2011 г.
oracle: Index Scans
http://aguppi.blogspot.com/2011/06/oracle-access-path.html
Что такое индекс oracle: Index
Типы Index Scans:
Index Unique Scans
Возвращает один rowid.
Происходит, если выражение использует индекс, который содержит ограничение
Hints
/*+ INDEX( tab_name idx1_name idx2_name ...) */
Этот хинт указывает оптимизатору использывать индекс, но не определённый путь индексного доступа.
Обычно не нужно указывать хинт для Index Unique Scans. Но если используем db link или таблица мала и оптимизатор выбирает Full Table Scan, то можно указать хинт.
Что такое индекс oracle: Index
Типы Index Scans:
- Index Unique Scans
- Index Range Scans
- Index Range Scans Descending
- Index Skip Scans
- Full Scans
- Fast Full Index Scans
- Index Joins
- Bitmap Joins
Index Unique Scans
Возвращает один rowid.
Происходит, если выражение использует индекс, который содержит ограничение
UNIQUE или PRIMARY KEY, которые гарантирую что будет возвращена только одна строка. Hints
/*+ INDEX( tab_name idx1_name idx2_name ...) */
Этот хинт указывает оптимизатору использывать индекс, но не определённый путь индексного доступа.
Обычно не нужно указывать хинт для Index Unique Scans. Но если используем db link или таблица мала и оптимизатор выбирает Full Table Scan, то можно указать хинт.
oracle: Rowid Scans
http://aguppi.blogspot.com/2011/06/oracle-access-path.html
Когда оптимизатор выбирает Rowid Scans
Обычно Rowid Scans это второй шаг после получения rowid из индекса.
Но если индекс содержит все столбцы возвращаемые выражением, то Rowid Scans не выполняется, т.к. все нужные данные уже находятся после index scan.
- Rowid определяет datafile и block, который содержит выбранную строку.
- Это быстрейший способ получить строку, поскольку rowid прямо указывает на расположение строки.
- Oracle получает rowid из выбранных с помощью конструкции WHERE либо с помощью index scan строк. Далее находит каждую выбранную строку таблицы с помощью rowid.
Когда оптимизатор выбирает Rowid Scans
Обычно Rowid Scans это второй шаг после получения rowid из индекса.
Но если индекс содержит все столбцы возвращаемые выражением, то Rowid Scans не выполняется, т.к. все нужные данные уже находятся после index scan.
Подписаться на:
Сообщения (Atom)
