Особенности параллельного выполнения sql в Oracle
Этот перевод делал в основном для себя, не утруждаясь коррекцией и стилем, за сим не обессудьте. Выражения с большой буквы (как то Parallel Slave Set или Data Flow Operation) считал за термины и не переводил либо давал перевод рядом в скобках, дабы избежать путаницы и искажения. Форматирование автора по возможности сохранено.
Оригинал тут:
Для параллельного
выполнения, требования должны быть
выполнены, по порядку:
1. Эффективный
Parallel Execution план
2. Достаточные
ресурсы доступны, в процессе выполнения
3. Отсутствие
существенных проблем распределения
Parallel Slaves (параллельных исполнителей).
Рассмотрим
по-порядку:
1.
Эффективный Parallel Execution план
Зачастую,
Parallel Execution считается "серебряной
пулей", способной решить проблемы
медленных запросов, выполняющихся в
один поток. Но, если последовательный
план не эффективен (например, неверный
порядок соединений или неверны сами
соединения или способы доступа), Parallel
Execution план будет также
неэффективен. Прежде всего, важно,
понимать каким должен быть эффективный
план, после этого может быть использован
Parallel Execution, если он применим для запроса.
Аспекты, что
применимы к последовательному выполнению,
также применимы и к Parallel Execution, но имеется
ряд особенностей:
Parallel Execution
Forced to
Serial
В некоторых
случаях Оракл в процессе разбора
оператора определяет, что он не может
использовать Parallel
Executions, хотя уже начал
строить Parallel Execution
план. Одна из основных причин -
использование пользовательских PL/SQL
функций, для которых не задействовано
параллельное выполнение, хотя я
встречается и в других ситуациях. Такое
поведение легко определить по плану –
он содержит одну или несколько операций
PX COORDINATOR FORCED
SERIAL:
------------------------------------------------------------------------------
| Id | Operation | Name | TQ |IN-OUT| PQ Distrib |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | |
| 1 | PX COORDINATOR FORCED SERIAL| | | | |
| 2 | PX SEND QC (RANDOM) | :TQ10003 | Q1,03 | P->S | QC (RAND) |
| 3 | HASH UNIQUE | | Q1,03 | PCWP | |
| 4 | PX RECEIVE | | Q1,03 | PCWP | |
| 5 | PX SEND HASH | :TQ10002 | Q1,02 | P->P | HASH |
|* 6 | HASH JOIN BUFFERED | | Q1,02 | PCWP | |
| 7 | PX RECEIVE | | Q1,02 | PCWP | |
| 8 | PX SEND HASH | :TQ10000 | Q1,00 | P->P | HASH |
| 9 | PX BLOCK ITERATOR | | Q1,00 | PCWC | |
| 10 | TABLE ACCESS FULL | T2 | Q1,00 | PCWP | |
| 11 | PX RECEIVE | | Q1,02 | PCWP | |
| 12 | PX SEND HASH | :TQ10001 | Q1,01 | P->P | HASH |
| 13 | PX BLOCK ITERATOR | | Q1,01 | PCWC | |
| 14 | TABLE ACCESS FULL | T2 | Q1,01 | PCWP | |
------------------------------------------------------------------------------
Будьте
внимательней, если вы видите операцию
PX
COORDINATOR
FORCED
SERIAL -
хоть план
выглядит как параллельный, оракл выполнит
его последовательно. Основная проблема
здесь, в том, что оптимизатор учитывает
сокращение стоимости актуальной для
параллельного выполнения. Например,
стоимость full
table
scan
при параллельности выглядит дешевле
доступа по индексу, но учитывая, что
запрос выполнится последовательно,
очень возможно, что это будет не лучший
выбор.
По
крайней мере, если выполнение пошло
последовательно, потенциальный всплеск
дополнительных операций блокировки
(на примере выше - это HASH
JOIN BUFFERED)
удастся избежать.
Объясню
природу дополнительных операций
блокировки ниже.
Additional
Blocking Operations (Дополнительные операции
блокировки)
В случае
параллельного выполнения, вещи выглядят
совсем по-другому. Оракл использует
модель Consumer/Producer
для не тривиальных Parallel
Executions планов, таким
образом, 2 сета Parallel Slaves
будут работать в одно и тоже время на
различных связанных операций единой
«Data Flow
Operation» (DFO
будет описана позже). Вследствие модели
Consumer/Producer
происходит, что оба Parallel
Slave Sets заняты
(один извлекает(produce),
другой использует(consume)
данные), но данные, соответственно, плану
выполнения, будут использованы следующей
операцией. Если следующая операция, по
плану, должна выполняться
отдельным Parallel Slave
Set (это можно увидеть из
TQ колонки плана), и нет
свободного слейв сета/процесса, который
может обработать данные, в таких случаях
ораклу требуется выполнить sync
points(точки синхронизации,
или операции блокировки), где данные
должны быть «запаркованы», до того
времени, как один из слейв сетов обводиться
для дальнейшей обработки данных.
В
текущих релизах Oracle,
можно просто определить «дополнительные
операции блокировки» в плане выполнения.
Это отдельные операции (BUFFER
SORT
не путайте с обычным BUFFER
SORT,
который также встречается в последовательном
плане) или одну их существующих операций,
дополненную опцией BUFFERED,
например HASH
JOIN
BUFFERED.
Итак,
есть 3 важных момента, которые следует
учитывать: