Monday, November 22, 2021

In-Memory Scan

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.

Does DEALLOCATE UNUSED or SHRINK SPACE will free space occupied by LOB segment?

Lets check how it works. My env is DB 19.20@Linux-x64 1) I created the table with 4 LOB columns of 4 different LOB types: BASICFILE BLOB, BA...