Ну, заголовок описывает то, с чем я недавно столкнулся при работе с базой данных Oracle.
Вот немного фона:
- Таблица, о которой идет речь, разбита хешем на 4 раздела.
- Параллельная степень таблицы 4.
- Ключ хеша равен PK.
- В таблице довольно много строк, около 200 млн.
- Индекс PK также разделен (локальный раздел).
- Параллельная степень индекса равна 1.
Хорошо, теперь у меня запрос странно себя ведет, когда я изменяю параллельную степень таблицы.
Если степень таблицы равна 4, это приводит к полному сканированию таблицы (согласованное параллельное полное сканирование таблицы), как показано в плане объяснения. На выполнение запроса уходит 30 минут или более.
Если уровень таблицы равен 1-3, он правильно использует индекс PK (сканирование диапазона, однопоточный) и возвращает результат через 20 секунд.
Если установить для степени таблицы и степени индекса значение 4, будет выполнено полное сканирование таблицы (такой же результат, как в первом сценарии выше).
Это поведение, однако, не происходит в другой базе данных, где у меня есть почти идентичный клон таблицы. Разница лишь в количестве записей. Таблица в другой базе данных имеет немного меньший размер (минус 1-2 миллиона). Меньшая таблица, также со степенью 4, не выполняет полное сканирование таблицы с тем же запросом.
Я потратил некоторое время на поиск в Google и нашел следующее о параллельном запросе:
Из официального документа Oracle
Высокая степень параллельности таблицы смещает оптимизатор к полному сканированию таблицы при сканировании диапазона. Изучите столбец DEGREE в ALL_TABLES для таблицы, чтобы определить степень параллелизма.
и от http://www.toadworld.com/Portals/0/GuyH/Articles/Oracle%20Parallel%20SQL%20Part%201.pdf
Параллельный запрос должен применяться, когда
SQL выполняет как минимум одну полную проверку таблицы, индекса или раздела
А с AskTom.com
Параллельный запрос подходит для определенного класса больших задач: очень большие проблемы
у которого нет другого решения. Параллельный запрос - мой последний путь решения
проблема производительности; это никогда не мой первый образ действий.
Кажется, что параллельное выполнение предназначено для обработки очень большого объема данных, когда не существует другого лучшего решения. Он пытается повысить производительность, выполняя параллельные процессы, при этом каждый ЦП (процесс) выделяется для работы с отдельной частью данных (диапазон блоков, разделы таблиц или индексные разделы). Так что он не предназначен для ускорения общего запроса или запроса, который не покрывает достаточную часть всей таблицы.
Верно ли мое понимание того, что параллель не должна использоваться в качестве средства для ускорения общего запроса?
Если да, значит ли это, что лучше всего отключать параллельное (степень как 0) и разрешать для конкретного запроса / операции с помощью подсказки или параллельного предложения?
И в дополнение ко всему, какой должна быть лучшая практика для настройки PARALLEL? Если то, что я хочу сделать, это обеспечить лучшую производительность чтения с помощью многопоточности, то какими должны быть настройки?
Здесь много вопросов. Большое спасибо заранее.