Part 1 Introduction: http://exadata-dba.blogspot.com/2021/11/in-memoryoracle.html
Part 2 IM Scan: http://exadata-dba.blogspot.com/2021/11/in-memoryoracle_22.html
Part 3 IM Join: http://exadata-dba.blogspot.com/2021/11/in-memoryoracle-part-3-im-join.html
Part 4: IM Aggregation http://exadata-dba.blogspot.com/2021/11/in-memporyoracle-part-4-im-aggregation.html
Посмотрим что из себя представляет IM Table Scan.
Начнём с таблицы ORDER_ITEMS:
Для демонстрации IM Scan напишем однотабличный запрос, который выбирает какую-то часть строк таблицы :
select count(quantity),
sum(quantity)
from soe.order_items
where product_id between X and X+10; -- 1%
PRODUCT_ID
Поле PRODUCT_ID выбрано потому, что по нему имеется индекс, т.е. для этого запроса возможны несколько способов выполнения: индексый доступ и полное табличное сканирование.
Сравним 4 способа доступа для нашего запроса:
• Индексный доступ (индекс по PRODUCT_ID)
• Full Table Scan (чтения с дисква в буферный кэш и FTS когда вся таблица в памяти)
• FTS Direct Read (чтения с диска в PGA, отсутствуют операции, необходимые для закрепления блоков в буферном кеше )
• In-Memory – обращение к данным в IM-пуле
Для отображения планов выполнения и времени будем использовать команды
SQL> set autotrace on
SQL> set timing on
Все команды будем выполнять в SQLcl
Разрешить/запретить IM для отдельных SQL-запросов можно следующими способами:
- на уровне SQL-запроса хинтами INMEMORY|NO_INMEMORY
- на уровне сессии командой alter session set INMEMORY_QUERY=DISABLE|ENABLE
- Доступ по индексу
select /*+ MONITOR INDEX(oi) NO_INMEMORY
gather_plan_statistics test1 */
count(*), sum(quantity)
from soe.order_items oi
where product_id between 500 and 510;
Дополнительно попробуйте хинты INDEX_RS_ASC(oi), INDEX_FFS(oi)
- Full Table Scan using BUFFER CACHE
alter session set "_serial_direct_read"= NEVER; -- Запрещаем Direct Read
select /*+ MONITOR FULL(oi) NO_INMEMORY
gather_plan_statistics test2 */
count(*), sum(quantity)
from soe.order_items oi
where product_id between 500 and 510;
alter session set "_serial_direct_read"= AUTO; -- Возвращаем значение по-умолчанию
- Full Table Scan Direct Read
alter session set "_serial_direct_read"= ALWAYS; -- Включаем Direct Read
select /*+ MONITOR FULL(oi) NO_INMEMORY
gather_plan_statistics test3 */
count(*), sum(quantity)
from soe.order_items oi where product_id between 500 and 510;
alter session set "_serial_direct_read"= AUTO;
- IN-MEMORY TABLE SCAN
select /*+ MONITOR test4 */
count(*), sum(quantity)
from soe.order_items oi
where product_id between 500 and 510;
Подведём итоги:
Способ |
COST |
Логических чтений |
CPU_TIME, ms |
Index |
5 121 000 |
741 590 |
2 380 |
FTS Buffered |
48 877 |
183 303 |
1 070 |
FTS Direct Read |
48 877 |
183 292 |
1 100 |
In-Memory |
2 071 |
13 |
19 |
In-Memory Expression
In-Memory Expression – это дополнительный виртуальный столбец в таблице, значения которого вычисляются на основе других столбцов. СУБД Oracle автоматически анализирует использование выражений в часто запускаемых запросах и автоматически принимает решение вычислять результаты для вычислительно-сложных комбинаций часто опрашиваемых столбцов.
Для автоматического распознавания и вычисления таких выражений/столбцов использутеся ESS (Expression Statistics Store) - хранилище статистики выражений, которое поддерживается оптимизатором для хранения статистики об оценке выражений. Для каждого сегмента ESS отслеживает частоту выполнения, стоимость, времени выполнения и т.д. ESS является постоянным по своей природе и имеет представление SGA для быстрого поиска выражений. Таким образом, оптимизатор СУБД Oracle автоматически распознаёт In-Memory Expression и выполняет SQL-запросы с использованием IME если считает, что это выгодно.
Когда СУБД Oracle загружает данные в IM column store и создаёт IM Compression Unit (IMCU), то то она одновременно создаёт/вычисляет значения виртуального столбца и сохраняет их в IM Expression Unit (IMEU):
Посмотрите на значения в столбце EXPRESSION_TEXT:
Partial IM Scan
Если IM pool ещё не заполнен (популяция не окончена, ещё в процессе), то оптимизатор принимает решение использовать IM Scan в следующих случаях:
- Если более 80% строк таблицы загружено в IM, то испольуется доступ к In-Memory и оставшиеся 20% строк берутся
из буферного кеша
- Если менее 80% загружено в IM, то используется In-Memory, а оставшиеся данные читаются с диска Direct Read (предварительно выполняется контрольная точка сегмента)
Пропорция 80/20 задаётся скрытым параметром.
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.