Одним из ключевых нововведений СУБД Oracle версии 12.1.0.2 стала опция In-Memory. Основная её идея заключается в том, что для выбранных таблиц вы можете легко активировать dual-format режим, который объединяет стандартный для Oracle DB построчный формат хранения данных на диске и поколоночный формат в оперативной памяти.

Соответствующее преобразование и дублирование данных в память происходит автоматически. Лично для меня это было большой новостью, так как я занимаюсь разработкой хранилищ данных (DWH) и имел опыт работы с column-oriented DBMS Sybase IQ и HP Vertica, которые созданы для хранилищ и аналитики. А Oracle предложил Column Store плюс In-Memory плюс все возможности любимой СУБД! По сути, с этим решением Oracle вышел на рынок аналитических in-memory баз данных (кто не читал, рекомендую отличную статью на Хабре со сравнением баз данных этого класса). Идея Oracle очень многообещающая, но на практике на моих тестовых примерах результаты, к большому сожалению, не впечатлили. Было это в прошлом году и я решил подождать пока технологию усовершенствуют. После выхода очередного патча с улучшениями In-Memory Option я вернулся к этому вопросу. Для статьи был выбран более объективный тест, который при желании смогут повторить читатели.

Прежде чем перейти к своему бенчмарку, приведу пару ссылок. В статье на Хабре в блоге компании Oracle подробное описание In-Memory Option и её фантастических результатов. В другой статье этого же блога приведён тест производительности, но используются только 2 таблицы и пару простых запросов.

TPC-H Benchmark


Для теста производительности я использовал tpc-h benchmark, который используется для сравнения производительности аналитических систем и хранилищ данных. Этот бенчмарк используют многие производители как СУБД, так и серверного оборудования. На странице tpc-h доступно много результатов, для публикации которых необходимо выполнить все требования спецификации на 136 страницах. Я публиковать официально свой тест не собирался, поэтому всем правилам строго не следовал. Также для упрощения процесса тестирования я воспользовался бесплатной версией программы Benchmark Factory for Databases.

TPC-H позволяет сгенерировать данные для 8-ми таблиц с использованием заданного параметра scale factor, который определяет примерный объём данных в гигабайтах. Я ограничился 2 Гб, так как больше не позволяет бесплатная версия Benchmark Factory. Итоговое количество строк в таблицах:
Таблица Кол-во строк
H_LINEITEM 11 996 782
H_ORDER 3 000 000
H_PARTSUPP 1 600 000
H_PART 400 000
H_CUSTOMER 300 000
H_SUPPLIER 20 000
H_NATION 25
H_REGION 5


Тест включает 22 SQL запроса различной сложности. Сравнивалось время выполнения с использованием In-Memory и без. При этом была сгенерирована следующая нагрузка: 8 виртуальных пользователей параллельно 3 раза по кругу выполняют все 22 запроса. В итоге оценивалось время выполнения 528-ми SQL запросов.

Тем, кому данный тест покажется недостаточно сложным, рекомендую обратить внимание на другой более свежий Benchmark — TPC-DS. В нём больше таблиц и значительно больше запросов – 99.

Стенд для тестирования


Ноутбук со следующими характеристиками:
— Intel Core i5-4210 CPU 1.70GHz – 4 cores; DDR3 16 Gb; SSD Disk.
ОС:
— MS Windows 8.1 x64
СУБД:
— Oracle Database 12c EE 12.1.0.2.0
— Interim patches (1): «WINDOWS DB BUNDLE PATCH 12.1.0.2.160531(64bit): 23179016»
DB Memory Configuration:
— memory_target = 10G;
— sga_target = 8G;
— inmemory_size = 3G;

Установка параметров In-Memory (IM)


Кроме установки параметра БД inmemory_size достаточно указать данные каких таблиц или их частей необходимо дублировать в кэше IM, всё остальное Oracle сделает за вас. Таким образом, перевести существующую БД на IM очень просто при наличии достаточного количества оперативной памяти. Переписывать ничего не нужно, можно только удалить индексы, которые не нужны для таблиц IM. Также отмечу стабильную работу, я не столкнулся ни с одним багом, связанным с IM.

В моём тесте все таблицы целиком отправились в IM:

ALTER TABLE MY_TABLE_NAME INMEMORY MEMCOMPRESS FOR QUERY HIGH PRIORITY CRITICAL;

  • MEMCOMPRESS FOR QUERY HIGH — оптимизированный для производительности запросов и для экономии памяти вариант (есть ещё 5 других вариантов, про которые можно прочитать в документации).
  • PRIORITY CRITICAL – определяет приоритет репликации в IM кэш.

Важным нюансом ещё является то, что данные в колонках хорошо сжимаются, что и делает Oracle. Следующий запрос показывает объём данных на диске, в IM и коэффициент сжатия:

select 
  SEGMENT_NAME,
  ROUND(SUM(BYTES)/1024/1024/1024,2) "ORIG SIZE, Gb",
  ROUND(SUM(INMEMORY_SIZE)/1024/1024/1024,2) "IM SIZE, Gb",
  ROUND(SUM(BYTES)/SUM(INMEMORY_SIZE),2) "COMPRESS RATIO"
from V$IM_SEGMENTS
group by SEGMENT_NAME
order by 2 desc;

SEGMENT_NAME
ORIG SIZE, GB
IM SIZE, GB
COMPRESS RATIO
H_LINEITEM
1,74
0,67
2,62
H_ORDER
0,39
0,35
1,1
H_PARTSUPP
0,12
0,08
1,58
H_PART
0,06
0,02
2,96
H_CUSTOMER
0,04
0,03
1,42
H_NATION
0
0
0,22
H_SUPPLIER
0
0
0,89
H_REGION
0
0
0,22

Результаты выполнения теста


#1 No In-Memory #2 In-Memory
Elapsed Time 7 мин. 23 сек. 6 мин. 26 сек.
Avg. Response Time (sec) 5.617 4.712

В заключение


Я не считаю, что по результатам одного любого теста можно делать какие-то категоричные выводы. Результаты могут сильно варьироваться в зависимости от моделей и объёмов данных, специфики запросов, конфигурации параметров СУБД, а также от аппаратной части. В качестве альтернативного примера приведу ссылку на некогда нашумевший бенчмарк, где компания Oracle сравнила производительность Oracle IM (на Exadata+Exalogic) и SAP HANA. Использовался SAP BW-EML Benchmark. В этом тесте аппаратно-программный комплекс от Oracle был на высоте.

Если у вас есть опыт использования Oracle In-Memory, буду рад прочитать об этом в комментариях.
Поделиться с друзьями
-->

Комментарии (24)


  1. yusman
    16.12.2016 15:11
    +1

    Спасибо за статью.
    А не замеряли нагрузку на CPU? Возможно ваши тесты ресурсоёмкие и упираются в процессор который и не дает нормально разогнаться IM


    1. mkrupenin
      16.12.2016 23:57

      Нагрузку на сервер анализировал, используя Oracle AWR отчёт. И в обоих случаях узким местом был процессор, т.к. оперативной памяти было достаточно для кеширования всего объёма данных. Цель была — оценить, какой прирост производительности можно получить за счёт IM Option. И в этом смысле оба теста имели равные условия.


      1. zhekappp
        17.12.2016 14:54

        А можете выложить какой-нибудь из AWR?


      1. zhekappp
        17.12.2016 15:38

        На мой взгляд в таком тесте, когда только 4 ядра и все в памяти не желательно иметь более 2-3-х работающих сессий к БД.
        Иначе, получается, что большая часть ожиданий будет не cpu, а wait for cpu — повылазят различные mutex, cursor pin и т.п.
        Отсюда может быть и небольшая разница в результатах, так как основное время ушло на не связанные с логикой обработки запросов ожидания.


        1. mkrupenin
          18.12.2016 00:39

          AWR отчёты могу на почту выслать.

          Момент с количеством параллельных сессий учитывался. Для сравнения вариант с 2-мя сессиями и 12-ю запусками (те же 528 итоговых запуска):
          1) 14 мин 13 сек. без IM
          2) 13 мин 07 сек. с IM
          Разница менее 10%.


          1. xtender
            25.12.2016 05:01

            Пропустил сообщение выше. Можно и мне на почту AWRы?


            1. xtender
              25.12.2016 15:36

              mkrupenin, подозрительно хорошие у вас результаты для noinmemory. Можно AWR и этого теста? А в идеале ashdump обоих тестов. Я прямо сейчас решил повторить ваш тест с помощью Benchmark factory (15-и дневная trial версия), с вашей же нагрузкой, так у меня noinmemory адско затыкается на direct path reads, и inmemory в несколько раз быстрее.


              1. mkrupenin
                25.12.2016 17:45

                Вышлю AWR'ы, только e-mail не нашёл.
                Я использовал Benchmark Factory for Databases Freeware v7.0.0.221 (не триал на 15 дней), но не думаю, что это принципиально.
                IM у меня был существенно быстрее (в 2-3 раза), когда не хватало памяти (итоговые параметры указаны в статье).


  1. yadaya
    16.12.2016 15:31
    +3

    Да, отличная статья.
    Что за запросы выполнялись поделитесь хотя бы?
    Где был bottleneck?
    То же самое на сжатых данных на диске пробовали?
    Тесты на холодную базу запускали?


    1. mkrupenin
      17.12.2016 00:21

      Поделюсь и запросами и ddl скриптами. Кому интересно, могу дать ссылку и на примерные планы выполнения запросов со статистикой.

      Bottleneck — CPU.

      Пробовал много дополнительных вариантов: несколько видов partitioning, без partitioning, c parallel и без, с компрессией вариант. При этом отдельные запросы специально не оптимизировались (индексами, хинтами,...). Делал это для того, чтобы показать ещё 1-2 быстрых способа оптимизации (например, parallel и/или db_big_table_cache_percent_target). Но на этом тесте и моём CPU интересных результатов не получилось и ограничился только IM Option.

      > Тесты на холодную базу запускали?
      Да, но так как каждый запрос выполнялся по 24 раза, это особой роли не играло. И 1-е выполнение не в разы было медленнее (диск SSD).


  1. Stawros
    17.12.2016 00:23

    Не имея структуры БД и 12-ого оракла перед глазами сложно сказать, но есть предположение, что в тесте большая часть запросов построена таким образом, чтобы данные извлекались по индексам/ключам. Но т.к. индексы не помещаются в память, то и выигрыша получено не было. Разница должна быть в таком тесте, где большая часть запросов построена на аналитических индексах — после их удаления и перемещения данных in-memory не будет необходимости в обращении к индексным сегментам.


    1. mkrupenin
      17.12.2016 00:28

      Я не совсем понял комментарий. Какие индексы в память не помещаются? Относительно чего не было выигрыша? И что понимаете под аналитическими индексами?
      Выше ссылки на ddl таблиц и запросы, просьба уточнить комментарий.


      1. Stawros
        17.12.2016 16:49

        Какие индексы в память не помещаются?

        Никакие. Т.е. full-scan по столбцам/таблицам в памяти может быть производительней доступа по индексу (например, если это низкоселективный многоколоночный индекс). Поэтому ускорение будет в первую очередь в запросах с долгим full / range / skip scan. Конечно, оптимизатор с большой долей вероятности сам определит, что нужно сканировать, а что нет, но минимальный анализ данных/структур проводить нужно — просто запихать всё в память и ждать космических скоростей не приходится, особенно если на вашем железе можно упереться в CPU. Смысл ведь IM в том чтобы разгрузить IO за счет памяти/CPU — если у вас второго не хватает, откуда тогда будет выигрыш в скорости?

        И что понимаете под аналитическими индексами?

        Индексы, созданные для оптимизации запросов, а не для обеспечения контроля целостности (pk/unique index) БД. Например для OLAP систем объём таких индексов может быть сравним с объёмом самих данных — в этом случае IM может давать огромный выигрыш — ведь не нужно сначала сканировать сегмент индексов и потом обращаться к таблице с данными — всё есть сразу в памяти. Плюс без таких индексов значительно сокращается время загрузки данных/обновления мат.представлений, сбор статистики.


        1. mkrupenin
          18.12.2016 01:29

          В бенчмарке TCP-H 22 запроса различной сложности как раз для DSS/OLAP систем. Ваши выводы будут интересны на конкретном примере.

          Первое, что я лично ожидал увидеть от Oracle IM на своих кейсах — это значительное ускорение аналитических запросов за счёт compressed column store. Допустим, есть fact таблица из 30 полей и XXX млн. строк, выбираю XX млн. строк и 3 поля. К примеру, СУБД Vertica ускоряет такие запросы минимум на порядок с 1 нодой.


        1. ggo
          18.12.2016 22:38

          Насчет индексов непонятно.

          Если таблица все целиком лежит в памяти, почему на индексы места не хватает? Понятно, что это дополнительное место. Но обычный кейс с индексами — они меньше таблиц.

          И если мы часть храним в памяти, часть на диске, очевидно преимущества от использования памяти нивелируются. И вместо прироста производительности на порядки, получаем на проценты.


          1. mkrupenin
            18.12.2016 22:41

            Я не писал, что индексам места в памяти не хватало. Я для column store в In-Memory индексов нет в принципе.


            1. ggo
              19.12.2016 08:08

              И с этой стороны тоже непонятно.
              Поколоночное хранение обычно используют для DWH, а DWH обычно предполагает, что объем таков, что ни в какую память не поместиться. Соответственно, остается поколоночное хранение для обычных баз. С дисками поколоночное хранение для обычных баз не используют из-за дороговизны модификации данных. С памятью наверно это перестает быть узким местом. Но это предположение.


  1. mkrupenin
    17.12.2016 00:37

    Есть ещё в планах выполнение аналогичного теста на полюбившихся мною СУБД Vertica и Exasol.


  1. krids
    17.12.2016 23:50

    Тоже гонял TPC-H (SF=50, таблица LINEITEM на 300M строк) на предмет сравнения отдельных запросов из буффер-кэша vs. инмемори-кэша. Из IMC получалось в среднем в 3 раза быстрее. Можете показать результат Q1 для обоих случаем с использованием /* parallel(4) */?

    Технология особенно интересна своей гибкостью (возможностью грузить в IMC отдельные колонки/партиции), но стоит ли оно того чтобы платить +50% к процессорной лицензии на EE это «нужно посмотреть» в каждом отдельном случае.

    По поводу результатов в бенчмарке SAP BW-EML: по-честному победить HANA'у не удалось, поэтому нагло читили с использованием матвьюшек, в результате закономерно не получили своего сертификата, что конечно же нисколько не мешает рассказывать «пастве» о том, как «мы порвали SAP на его же бенчмарке поэтому он наш результат не сертифицирует»


    1. mkrupenin
      18.12.2016 01:13

      50 Гб конечно интереснее. На какой конфигурации сервера тестировали? Как в буферный кэш все данные отправляли? У меня разница в разы получалась только тогда, когда памяти на кэш не хватало.

      Результаты для Q1:
      no IM no parallel — 6.62 сек.
      no IM parallel(4) — 5.88 сек.
      IM no parallel — 6.47 сек.
      IM no parallel(4) — 3.15 сек

      Планы и статистика по ссылке.

      Но по сумме всех запросов IM+parallel мне не давал выигрыш в 2 раза.


      1. krids
        18.12.2016 17:23

        Ясно. Спасибо.

        У меня была виртуалка на 16vCPU на стареньком IBM x3850M2 (4 x 4 core Xeon X7350) + 60GB RAM.

        LINEITEM и ORDERS были непартицированные с опцией COMPRESS FOR DIRECT_LOAD, загружены sqlldr'ом. Раздувал sga_target и прогонял запросы первым проходом, чтобы все таблицы закешировались. В последующие запуски смотрел nmon'ом, чтобы отсутствовал disk i/o.


  1. skullodrom
    21.12.2016 01:35

    >можно только удалить индексы, которые не нужны для таблиц IM
    Если не секрет, откуда у вас такая уверенность, так в доке написано?
    Просто индексы нужны не только для фул скана, а для того чтобы быстро по дереву в 4-5 шагов найти одну строчку с достаточно уникальными атрибутами среди триллиона строк. Пример думаю не сложно представить.

    Честное тестирование это конечно очень хорошо, особенно из первых рук.
    Хотелось бы увидеть тот же тест на Вертике, хотя это совсем другой класс продктов, но под ваши тяжелые запросы думаю самое-то.
    Хотелось бы конечно и на Сап Ханне, но это нужно к вендору или у кого она случайно завалялась.
    Я наверное попробую сделать этот же тест на MS SQL 2016


    1. mkrupenin
      21.12.2016 23:55

      Про индексы. Конечно же каждый кейс (таблица, конкретный индекс, характерные запросы,...) нужно рассматривать индивидуально. Если после включения IM необходимость в индексе пропадает, то удаляем, нет — оставляем. Например, в случае факт таблицы для аналитики актуальность большинства индексов скорее пропадёт.
      Аналогичный тест на Vertica есть в планах. SAP HANA в ближайшее время вряд ли.
      Результаты теста на MS SQL будет интересно почитать, особенно в части IM и column store.


  1. xtender
    25.12.2016 04:42

    А отчет AWR есть? У меня сильное подозрение, что у вас слишком много ушло тупо ожидая процессора (CPU queue length смотрели?), т.к. ноут у вас 4-х ядерный, а нагрузку гнали в 8 пользователей, и помимо оракла еще и сам бенчмарк работал, да и еще что-нибудь, наверное. Попробуйте в 2-3 пользователя