Скорость работы с памятью для различных типов таблицы настроек
Обновлено: 21.11.2024
В этом разделе рассматриваются некоторые рекомендации по использованию операций запроса и сканирования в Amazon DynamoDB.
Вопросы производительности сканирования
В целом операции сканирования менее эффективны, чем другие операции в DynamoDB. Операция сканирования всегда сканирует всю таблицу или вторичный индекс. Затем он отфильтровывает значения, чтобы получить желаемый результат, фактически добавляя дополнительный шаг удаления данных из набора результатов.
По возможности следует избегать использования операции сканирования для большой таблицы или индекса с фильтром, который удаляет много результатов. Кроме того, по мере роста таблицы или индекса операция сканирования замедляется. Операция сканирования проверяет каждый элемент на наличие запрошенных значений и может использовать предоставленную пропускную способность для большой таблицы или индекса за одну операцию. Для более быстрого отклика спроектируйте свои таблицы и индексы так, чтобы ваши приложения могли использовать Query вместо Scan . (Для таблиц вы также можете использовать API GetItem и BatchGetItem.)
В качестве альтернативы спроектируйте приложение для использования операций сканирования таким образом, чтобы свести к минимуму влияние на частоту запросов.
Как избежать внезапных всплесков активности чтения
При создании таблицы вы устанавливаете для нее требования к единицам емкости для чтения и записи. Для операций чтения единицы емкости выражаются как количество строго согласованных запросов на чтение данных объемом 4 КБ в секунду. Для окончательно согласованных операций чтения единица емкости чтения составляет два запроса на чтение по 4 КБ в секунду. Операция сканирования по умолчанию выполняет последовательное чтение и может возвращать до 1 МБ (одну страницу) данных. Таким образом, один запрос сканирования может потреблять (размер страницы 1 МБ / размер элемента 4 КБ) / 2 (в конечном итоге согласованные чтения) = 128 операций чтения. Если вместо этого вы запросите строго согласованное чтение, операция сканирования потребует в два раза больше выделенной пропускной способности — 256 операций чтения.
Это представляет собой внезапный всплеск использования по сравнению с настроенной емкостью чтения для таблицы. Такое использование единиц емкости при сканировании не позволяет другим потенциально более важным запросам для той же таблицы использовать доступные единицы емкости. В результате вы, скорее всего, получите исключение ProvisionedThroughputExceeded для этих запросов.
Проблема заключается не только в внезапном увеличении единиц емкости, которые использует сканирование. Сканирование также, вероятно, использует все свои единицы емкости из одного и того же раздела, потому что сканирование запрашивает чтение элементов, которые находятся рядом друг с другом в разделе. Это означает, что запрос попадает в тот же раздел, что приводит к потреблению всех его единиц емкости и регулированию других запросов к этому разделу. Если запрос на чтение данных распределен по нескольким разделам, операция не будет ограничивать определенный раздел.
На следующей диаграмме показано влияние внезапного всплеска использования единицы емкости операциями запроса и сканирования, а также его влияние на другие ваши запросы к той же таблице.
Как показано здесь, скачок использования может повлиять на выделенную пропускную способность таблицы несколькими способами:
Хорошо: равномерное распределение запросов и размеров
Не так хорошо: частые запросы в пакетах
Плохо: несколько случайных больших запросов
Плохо: большие операции сканирования
Вместо большой операции сканирования можно использовать следующие методы, чтобы свести к минимуму влияние сканирования на выделенную пропускную способность таблицы.
Уменьшить размер страницы
Поскольку операция сканирования считывает всю страницу (по умолчанию 1 МБ), вы можете уменьшить влияние операции сканирования, задав меньший размер страницы. Операция Scan предоставляет параметр Limit, который можно использовать для установки размера страницы для вашего запроса. Каждый запрос Query или Scan с меньшим размером страницы использует меньше операций чтения и создает «паузу» между каждым запросом. Например, предположим, что размер каждого элемента составляет 4 КБ, а размер страницы задан равным 40 элементам. Тогда запрос Query будет потреблять только 20 операций чтения, в конечном счете согласованных, или 40 операций чтения со строгой согласованностью. Большее количество небольших операций запроса или сканирования позволит успешно выполнять другие важные запросы без ограничения скорости.
Изолировать операции сканирования
DynamoDB легко масштабируется. В результате приложение может создавать таблицы для разных целей, возможно, даже дублируя содержимое нескольких таблиц. Вы хотите выполнить сканирование таблицы, которая не использует критически важный трафик. Некоторые приложения справляются с этой нагрузкой, ежечасно переключая трафик между двумя таблицами — одной для критического трафика и одной для учета. Другие приложения могут делать это, выполняя каждую запись в двух таблицах: "критически важной" таблице и "теневой" таблице.
Настройте приложение таким образом, чтобы оно повторяло любой запрос, который получает код ответа, указывающий, что вы превысили предоставленную пропускную способность. Или увеличьте подготовленную пропускную способность для таблицы с помощью операции UpdateTable. Если у вас есть временные всплески рабочей нагрузки, из-за которых пропускная способность иногда превышает подготовленный уровень, повторите запрос с экспоненциальной задержкой. Дополнительные сведения о реализации экспоненциальной отсрочки см. в разделе Повторные попытки при ошибках и экспоненциальная отсрочка.
Использование преимуществ параллельного сканирования
Многим приложениям выгоднее использовать параллельные операции сканирования, а не последовательные. Например, приложение, которое обрабатывает большую таблицу исторических данных, может выполнять параллельное сканирование намного быстрее, чем последовательное. Несколько рабочих потоков в фоновом «чистильном» процессе могут сканировать таблицу с низким приоритетом, не влияя на производственный трафик. В каждом из этих примеров параллельное сканирование используется таким образом, чтобы не лишать другие приложения выделенных ресурсов пропускной способности.
Несмотря на то, что параллельное сканирование может быть полезным, оно может сильно требовать пропускной способности. При параллельном сканировании ваше приложение имеет несколько рабочих процессов, которые одновременно выполняют операции сканирования. Это может быстро израсходовать всю предоставленную емкость чтения вашей таблицы. В этом случае другие приложения, которым необходим доступ к таблице, могут быть ограничены.
Параллельное сканирование может быть правильным выбором, если выполняются следующие условия:
Размер таблицы составляет 20 ГБ или больше.
Подготовленная пропускная способность чтения таблицы используется не полностью.
Операции последовательного сканирования выполняются слишком медленно.
Выбор всех сегментов
Наилучшая настройка для TotalSegments зависит от конкретных данных, предоставленных настроек пропускной способности таблицы и ваших требований к производительности. Возможно, вам придется поэкспериментировать, чтобы сделать это правильно. Мы рекомендуем начать с простого соотношения, например, один сегмент на 2 ГБ данных. Например, для таблицы размером 30 ГБ вы можете установить TotalSegments равным 15 (30 ГБ / 2 ГБ). Тогда ваше приложение будет использовать 15 рабочих процессов, каждый из которых будет сканировать отдельный сегмент.
Вы также можете выбрать значение TotalSegments на основе клиентских ресурсов. Вы можете установить TotalSegments на любое число от 1 до 1000000, и DynamoDB позволяет сканировать это количество сегментов. Например, если ваш клиент ограничивает количество потоков, которые могут выполняться одновременно, вы можете постепенно увеличивать значение TotalSegments, пока не добьетесь максимальной производительности сканирования в своем приложении.
Контролируйте параллельные сканирования, чтобы оптимизировать использование выделенной пропускной способности, а также следите за тем, чтобы другие приложения не испытывали нехватки ресурсов. Увеличьте значение TotalSegments, если вы не используете всю подготовленную пропускную способность, но по-прежнему сталкиваетесь с регулированием запросов на сканирование. Уменьшите значение TotalSegments, если запросы сканирования потребляют больше выделенной пропускной способности, чем вы хотите использовать.
Amazon Redshift обеспечивает чрезвычайно быстрое выполнение запросов, используя эти функции повышения производительности.
Темы
Массовая параллельная обработка
Массово-параллельная обработка (MPP) позволяет быстро выполнять самые сложные запросы, работающие с большими объемами данных. Несколько вычислительных узлов выполняют всю обработку запросов, ведущую к агрегированию окончательных результатов, при этом каждое ядро каждого узла выполняет одни и те же скомпилированные сегменты запросов для частей всех данных.
Amazon Redshift распределяет строки таблицы по вычислительным узлам, чтобы данные можно было обрабатывать параллельно. Выбрав соответствующий ключ распределения для каждой таблицы, вы можете оптимизировать распределение данных, чтобы сбалансировать рабочую нагрузку и свести к минимуму перемещение данных от узла к узлу. Дополнительные сведения см. в разделе Выбор наилучшего стиля распространения.
При загрузке данных из неструктурированных файлов используется преимущества параллельной обработки за счет распределения рабочей нагрузки между несколькими узлами при одновременном чтении из нескольких файлов. Дополнительные сведения о том, как загружать данные в таблицы, см. в разделе Рекомендации Amazon Redshift по загрузке данных.
Хранение данных в столбцах
Хранение столбцов для таблиц базы данных значительно снижает общие требования к дисковому вводу-выводу и является важным фактором оптимизации производительности аналитических запросов. Хранение информации таблицы базы данных в виде столбцов уменьшает количество запросов ввода-вывода к диску и уменьшает объем данных, которые необходимо загрузить с диска. Загрузка меньшего количества данных в память позволяет Amazon Redshift выполнять больше обработки в памяти при выполнении запросов. Более подробное объяснение см. в разделе Хранилище столбцов.
Если столбцы отсортированы надлежащим образом, обработчик запросов может быстро отфильтровать большое подмножество блоков данных. Дополнительные сведения см. в разделе Выбор наилучшего ключа сортировки.
Сжатие данных
Сжатие данных снижает требования к хранилищу, тем самым сокращая дисковые операции ввода-вывода, что повышает производительность запросов.При выполнении запроса сжатые данные считываются в память, а затем распаковываются во время выполнения запроса. Загрузка меньшего количества данных в память позволяет Amazon Redshift выделять больше памяти для анализа данных. Поскольку в колоночном хранилище схожие данные хранятся последовательно, Amazon Redshift может применять кодировки с адаптивным сжатием, специально привязанные к столбчатым типам данных. Лучший способ включить сжатие данных в столбцах таблицы — разрешить Amazon Redshift применять оптимальные кодировки сжатия при загрузке таблицы данными. Дополнительные сведения об использовании автоматического сжатия данных см. в разделе Загрузка таблиц с автоматическим сжатием.
Оптимизатор запросов
Механизм выполнения запросов Amazon Redshift включает оптимизатор запросов, который поддерживает MPP, а также использует преимущества хранилища данных, ориентированного на столбцы. В оптимизаторе запросов Amazon Redshift реализованы значительные усовершенствования и расширения для обработки сложных аналитических запросов, которые часто включают соединения нескольких таблиц, подзапросы и агрегирование. Дополнительные сведения об оптимизации запросов см. в разделе Настройка производительности запросов.
Кэширование результатов
Чтобы сократить время выполнения запросов и повысить производительность системы, Amazon Redshift кэширует результаты определенных типов запросов в памяти на ведущем узле. Когда пользователь отправляет запрос, Amazon Redshift проверяет кэш результатов на наличие действительной кэшированной копии результатов запроса. Если в кэше результатов найдено совпадение, Amazon Redshift использует кэшированные результаты и не выполняет запрос. Кэширование результатов прозрачно для пользователя.
Кэширование результатов включено по умолчанию. Чтобы отключить кэширование результатов для текущего сеанса, установите для параметра enable_result_cache_for_session значение off .
Amazon Redshift использует кешированные результаты для нового запроса, если выполняются все следующие условия:
Пользователь, отправляющий запрос, имеет право доступа к объектам, используемым в запросе.
Таблица или представления в запросе не были изменены.
В запросе не используется функция, которая должна выполняться при каждом выполнении, например GETDATE.
Запрос не ссылается на внешние таблицы Amazon Redshift Spectrum.
Параметры конфигурации, которые могут повлиять на результаты запроса, не изменились.
Запрос синтаксически соответствует кэшированному запросу.
Чтобы максимально повысить эффективность кэширования и эффективного использования ресурсов, Amazon Redshift не кэширует некоторые большие наборы результатов запросов. Amazon Redshift определяет необходимость кэширования результатов запроса на основе ряда факторов. Эти факторы включают количество записей в кэше и тип экземпляра вашего кластера Amazon Redshift.
Чтобы определить, использовал ли запрос кэш результатов, запросите системное представление SVL_QLOG. Если запрос использовал кэш результатов, столбец source_query возвращает идентификатор исходного запроса. Если кэширование результатов не использовалось, значение столбца source_query равно NULL.
В следующем примере показано, что запросы, отправленные с идентификатором пользователя 104 и идентификатором пользователя 102, используют кеш результатов запросов, выполненных с идентификатором пользователя 100.
Скомпилированный код
Узел-лидер распределяет полностью оптимизированный скомпилированный код по всем узлам кластера. Компиляция запроса устраняет накладные расходы, связанные с интерпретатором, и, следовательно, увеличивает скорость выполнения, особенно для сложных запросов. Скомпилированный код кэшируется и распределяется между сеансами одного и того же кластера, поэтому последующие выполнения одного и того же запроса будут выполняться быстрее, часто даже с другими параметрами.
Подсистема выполнения компилирует разный код для протокола подключения JDBC и для протоколов подключения ODBC и psql (libq), поэтому два клиента, использующие разные протоколы, будут нести первоначальные затраты на компиляцию кода. Однако другие клиенты, использующие тот же протокол, выиграют от совместного использования кэшированного кода.
Эта статья предназначена для разработчиков, которые спешат изучить основы производительности In-Memory OLTP в Microsoft SQL Server и базе данных SQL Azure.
Для In-Memory OLTP в этой статье представлены следующие сведения:
- Краткое описание функций.
- Примеры основного кода, реализующие функции.
SQL Server и база данных SQL имеют лишь незначительные различия в поддержке технологий In-Memory.
Некоторые блоггеры называют In-Memory OLTP Hekaton.
Преимущества встроенных в память функций
SQL Server предоставляет функции In-Memory, которые могут значительно повысить производительность многих прикладных систем. В этом разделе описаны самые простые соображения.
Функции для OLTP (онлайн-обработка транзакций)
Системы, которые должны одновременно обрабатывать большое количество SQL INSERT, являются отличными кандидатами для функций OLTP.
- Наши тесты показывают, что повышение скорости от 5 до 20 раз достигается за счет внедрения функций In-Memory.
Системы, обрабатывающие тяжелые вычисления на языке Transact-SQL, являются отличными кандидатами.
- Хранимая процедура, предназначенная для сложных вычислений, может выполняться в 99 раз быстрее.
Позже вы можете ознакомиться со следующими статьями, в которых демонстрируется повышение производительности за счет In-Memory OLTP:
-
предлагает небольшую демонстрацию большего потенциального прироста производительности. предлагает более масштабную демонстрацию.
Функции операционной аналитики
In-Memory Analytics относится к операторам SQL SELECT, которые объединяют транзакционные данные, как правило, путем включения предложения GROUP BY. Тип индекса под названием columnstore занимает центральное место в операционной аналитике.
Есть два основных сценария:
-
Пакетная операционная аналитика относится к процессам агрегирования, которые выполняются либо в нерабочее время, либо на дополнительном оборудовании, на котором есть копии транзакционных данных.
- Копия на диск предназначена для стандартного восстановления после выключения и перезапуска сервера или базы данных. Эта двойственность памяти и диска полностью скрыта от вас и вашего кода.
- Мы видели, что собственная компиляция приводит к продолжительности, составляющей 1/100 от интерпретируемой продолжительности.
- Скомпилированные в собственном коде пользовательские функции (UDF), которые являются скалярными.
- Триггеры, скомпилированные в собственном коде.
- CREATE INDEX и DROP INDEX нельзя запускать для таблицы, оптимизированной для памяти, используйте ALTER TABLE . Вместо этого ДОБАВЬТЕ/УДАЛИТЕ ИНДЕКС.
- Подробнее см. в разделе Изменение таблиц, оптимизированных для памяти.
- Когда для дисковой таблицы создается несколько версий строки, версии строк временно сохраняются в базе данных tempdb.
- Скомпилированная в собственном коде хранимая процедура не может получить доступ к таблице на диске. Собственный процесс может получить доступ только к таблицам, оптимизированным для памяти.
- Когда собственный процесс запускается в первый раз после того, как сервер или база данных были в последний раз переведены в оперативный режим, собственный процесс необходимо перекомпилировать один раз. Это вызывает задержку перед запуском собственного процесса.
- Скомпилированные в собственном коде хранимые процедуры (собственные процедуры).
- Скомпилированные в собственном коде скалярные определяемые пользователем функции.
- Триггеры, скомпилированные в собственном коде (нативные триггеры).
- Только триггеры, скомпилированные в собственном коде, разрешены для таблиц, оптимизированных для памяти.
Скомпилированная пользовательская функция (UDF) в собственном коде работает быстрее, чем интерпретируемая UDF. Вот некоторые моменты, которые следует учитывать при работе с пользовательскими функциями:
- Когда оператор T-SQL SELECT использует определяемую пользователем функцию, она всегда вызывается один раз для каждой возвращаемой строки.
- Пользовательские функции никогда не запускаются встроенными, а всегда вызываются.
- Скомпилированное различие менее важно, чем накладные расходы на повторные вызовы, присущие всем пользовательским функциям.
- Тем не менее накладные расходы на вызовы UDF часто приемлемы на практическом уровне.
Для получения тестовых данных и пояснений о производительности собственных UDF см.:
Руководство по документации для таблиц, оптимизированных для памяти
См. другие статьи, в которых обсуждаются особенности таблиц, оптимизированных для памяти:
- Отчет об анализе производительности транзакций в SQL Server Management Studio поможет вам оценить, улучшит ли In-Memory OLTP производительность вашего приложения базы данных.
- Используйте помощника по оптимизации памяти, чтобы помочь вам перенести таблицу базы данных на диске в выполняющуюся в памяти OLTP.
- Хранилище, используемое таблицами, оптимизированными для памяти, может быть намного больше, чем их размер в памяти, и это влияет на размер резервной копии базы данных.
- Включает информацию о логике повторных попыток в T-SQL для транзакций в таблицах, оптимизированных для памяти.
- Поддерживаемые и неподдерживаемые типы T-SQL и данных для табличных и собственных процессов, оптимизированных для памяти.
Руководство по документации для нативных процедур
В следующей статье и ее дочерних статьях в оглавлении (TOC) объясняются подробности о хранимых процедурах, скомпилированных в собственном коде.
Ссылки по теме
Вот статьи, предлагающие код, демонстрирующий прирост производительности, которого можно добиться с помощью In-Memory OLTP:
Подсистема хранения MEMORY (ранее известная как HEAP) создает специальные таблицы с содержимым, которое хранится в памяти. Поскольку данные уязвимы для сбоев, проблем с оборудованием или перебоев в подаче электроэнергии, используйте эти таблицы только в качестве временных рабочих областей или кэшей только для чтения для данных, извлеченных из других таблиц.
Таблица 16.4. Возможности механизма хранения MEMORY
th>Функция Поддержка Индексы B-tree Да Резервное копирование/восстановление на момент времени (реализовано на сервере , а не в механизме хранения.) Да Поддержка базы данных кластера Нет Кластеризованные индексы Нет Сжатые данные Нет Кэши данных Н/Д Зашифрованные данные Да (Реализовано на сервере с помощью функций шифрования.) Поддержка внешнего ключа Нет Индексы полнотекстового поиска Нет Поддержка типа геопространственных данных Нет Поддержка геопространственного индексирования < td>НетХеш-индексы Да Кеши индексов Н/Д Детализация блокировки Таблица MVCC Нет Поддержка репликации (реализована на сервере, а не в механизме хранения.) Ограничено (см. обсуждение далее в этом разделе.) Ограничения на объем памяти ОЗУ Индексы Т-дерева Нет Транзакции Нет Обновление статистика для словаря данных Да Когда использовать кластер MEMORY или NDB
Разработчикам, желающим развернуть приложения, использующие механизм хранения MEMORY для важных, высокодоступных или часто обновляемых данных, следует подумать, является ли NDB Cluster лучшим выбором. Типичный вариант использования механизма MEMORY включает следующие характеристики:
Операции с временными, некритическими данными, например управление сеансом или кэширование. Когда сервер MySQL останавливается или перезапускается, данные в таблицах MEMORY теряются.
Хранилище в оперативной памяти для быстрого доступа и низкой задержки. Объем данных может полностью помещаться в памяти, не заставляя операционную систему подкачивать страницы виртуальной памяти.
Шаблон доступа к данным только для чтения или преимущественно для чтения (ограниченные обновления).
NDB Cluster предлагает те же функции, что и механизм MEMORY, но с более высоким уровнем производительности, а также предоставляет дополнительные функции, недоступные для MEMORY:
Блокировка на уровне строк и многопоточная работа для снижения конкуренции между клиентами.
Масштабируемость даже при использовании смесей операторов, включающих запись.
Дополнительная операция с резервным копированием на диск для обеспечения надежности данных.
Архитектура без общего доступа и работа с несколькими хостами без единой точки отказа обеспечивают доступность на уровне 99,999 %.
Автоматическое распределение данных по узлам; разработчикам приложений не нужно создавать собственные решения для сегментирования или секционирования.
Поддержка типов данных переменной длины (включая BLOB и TEXT ), не поддерживаемых MEMORY .
Разметка
Таблицы MEMORY нельзя секционировать.
Характеристики эффективности
Производительность MEMORY ограничена конфликтами, возникающими из-за однопоточного выполнения и накладных расходов на блокировку таблицы при обработке обновлений. Это ограничивает масштабируемость при увеличении нагрузки, особенно для комбинаций операторов, включающих запись.
Несмотря на обработку в памяти для таблиц MEMORY, они не обязательно быстрее, чем таблицы InnoDB на загруженном сервере, для запросов общего назначения или при рабочей нагрузке чтения/записи. В частности, блокировка таблиц, связанная с выполнением обновлений, может замедлить одновременное использование таблиц MEMORY из нескольких сеансов.
В зависимости от типов запросов, выполняемых к таблице MEMORY, вы можете создавать индексы либо в виде хэш-структуры данных по умолчанию (для поиска отдельных значений на основе уникального ключа), либо в виде структуры данных B-дерева общего назначения ( для всех видов запросов, включающих равенство, неравенство или операторы диапазона, такие как меньше или больше). В следующих разделах показан синтаксис для создания обоих типов индексов. Распространенной проблемой производительности является использование хэш-индексов по умолчанию в рабочих нагрузках, где индексы B-дерева более эффективны.
Характеристики таблиц MEMORY
Ядро памяти MEMORY не создает никаких файлов на диске. Определение таблицы хранится в словаре данных MySQL.
Таблицы MEMORY имеют следующие характеристики:
Пространство для таблиц MEMORY выделяется небольшими блоками. Таблицы используют 100% динамическое хеширование для вставок. Не требуется области переполнения или дополнительного пространства для клавиш. Для бесплатных списков не требуется дополнительного места. Удаленные строки помещаются в связанный список и повторно используются при вставке новых данных в таблицу. Таблицы MEMORY также не имеют проблем, обычно связанных с операциями удаления и вставки в хэш-таблицах.
В таблицах MEMORY используется формат хранения строк фиксированной длины. Типы переменной длины, такие как VARCHAR, хранятся с использованием фиксированной длины.
Таблицы MEMORY не могут содержать столбцы BLOB или TEXT.
MEMORY включает поддержку столбцов AUTO_INCREMENT.
Таблицы Non-TEMPORARY MEMORY совместно используются всеми клиентами, как и любые другие таблицы non-TEMPORARY.
Операции DDL для таблиц MEMORY
Чтобы создать таблицу MEMORY, укажите условие ENGINE=MEMORY в операторе CREATE TABLE.
Как видно из названия движка, таблицы MEMORY хранятся в памяти. По умолчанию они используют хэш-индексы, что делает их очень быстрыми для поиска с одним значением и очень полезными для создания временных таблиц. Однако, когда сервер выключается, все строки, хранящиеся в таблицах MEMORY, теряются. Сами таблицы продолжают существовать, поскольку их определения хранятся в словаре данных MySQL, но они пусты при перезапуске сервера.
В этом примере показано, как можно создать, использовать и удалить таблицу MEMORY:
Максимальный размер таблиц MEMORY ограничен системной переменной max_heap_table_size, значение по умолчанию которой составляет 16 МБ. Чтобы применить различные ограничения размера для таблиц MEMORY, измените значение этой переменной. Действующее значение для CREATE TABLE или последующего ALTER TABLE или TRUNCATE TABLE — это значение, используемое в течение всего срока службы таблицы. При перезапуске сервера максимальный размер существующих таблиц MEMORY также устанавливается равным глобальному значению max_heap_table_size. Вы можете установить размер для отдельных таблиц, как описано далее в этом разделе.
Индексы
Общие характеристики B-деревьев и хэш-индексов см. в Разделе 8.3.1, «Как MySQL использует индексы».
Таблицы MEMORY могут иметь до 64 индексов на таблицу, 16 столбцов на индекс и максимальную длину ключа 3072 байта.
Если хеш-индекс таблицы MEMORY имеет высокую степень дублирования ключей (много записей индекса содержат одно и то же значение), обновления таблицы, влияющие на значения ключей, и все удаления выполняются значительно медленнее. Степень этого замедления пропорциональна степени дублирования (или обратно пропорциональна кардинальности индекса). Вы можете использовать индекс BTREE, чтобы избежать этой проблемы.
Таблицы MEMORY могут иметь неуникальные ключи. (Это необычная функция для реализаций хэш-индексов.)
Индексируемые столбцы могут содержать значения NULL.
Созданные пользователем и временные таблицы
Если внутренняя временная таблица становится слишком большой, сервер автоматически преобразует ее в хранилище на диске, как описано в Разделе 8.4.4, «Использование внутренней временной таблицы в MySQL».
Созданные пользователем таблицы MEMORY никогда не преобразуются в дисковые таблицы.
Загрузка данных
Чтобы заполнить таблицу MEMORY при запуске сервера MySQL, вы можете использовать системную переменную init_file. Например, вы можете поместить такие операторы, как INSERT INTO. ВЫБЕРИТЕ или ЗАГРУЗИТЕ ДАННЫЕ в файл, чтобы загрузить таблицу из постоянного источника данных, и используйте init_file, чтобы назвать файл. См. Раздел 5.1.8, «Системные переменные сервера», и Раздел 13.2.7, «Заявление LOAD DATA».
Таблицы MEMORY и репликация
Когда исходный сервер репликации выключается и перезапускается, его таблицы MEMORY становятся пустыми. Чтобы воспроизвести этот эффект на реплики, в первый раз, когда источник использует данную таблицу MEMORY после запуска, он регистрирует событие, которое уведомляет реплики о том, что таблица должна быть очищена путем записи оператора DELETE или (из MySQL 8.0.22) TRUNCATE TABLE для эту таблицу в двоичный журнал. Когда сервер-реплика выключается и перезапускается, его таблицы MEMORY также становятся пустыми, и он записывает оператор DELETE или (из MySQL 8.0.22) TRUNCATE TABLE в свой собственный двоичный журнал, который передается на все нижестоящие реплики.
При использовании таблиц MEMORY в топологии репликации в некоторых ситуациях таблица в источнике и таблица в реплике могут отличаться. Информацию о том, как обрабатывать каждую из этих ситуаций для предотвращения устаревших операций чтения или ошибок, см. в Разделе 17.5.1.21, «Репликация и таблицы MEMORY».
Управление использованием памяти
Серверу требуется достаточно памяти для обслуживания всех таблиц MEMORY, которые используются одновременно.
Память не восстанавливается, если вы удаляете отдельные строки из таблицы MEMORY. Память освобождается только при удалении всей таблицы. Память, которая ранее использовалась для удаленных строк, повторно используется для новых строк в той же таблице. Чтобы освободить всю память, используемую таблицей MEMORY, когда вам больше не нужно ее содержимое, выполните DELETE или TRUNCATE TABLE, чтобы удалить все строки, или полностью удалите таблицу, используя DROP TABLE. Чтобы освободить память, используемую удаленными строками, используйте ALTER TABLE ENGINE=MEMORY для принудительного перестроения таблицы.
Память, необходимая для одной строки в таблице MEMORY, рассчитывается с использованием следующего выражения:
ALIGN() представляет коэффициент округления, чтобы длина строки была точно кратна размеру указателя char. sizeof(char*) равен 4 на 32-битных машинах и 8 на 64-битных машинах.
Как упоминалось ранее, системная переменная max_heap_table_size устанавливает предел максимального размера таблиц MEMORY. Чтобы управлять максимальным размером отдельных таблиц, установите значение сеанса этой переменной перед созданием каждой таблицы. (Не изменяйте глобальное значение max_heap_table_size, если вы не собираетесь использовать это значение для таблиц MEMORY, созданных всеми клиентами.) В следующем примере создаются две таблицы MEMORY с максимальным размером 1 МБ и 2 МБ соответственно:
Обе таблицы возвращаются к глобальному значению max_heap_table_size сервера, если сервер перезапускается.
Вы также можете указать параметр таблицы MAX_ROWS в операторах CREATE TABLE для таблиц MEMORY, чтобы указать количество строк, которые вы планируете хранить в них. Это не позволяет таблице увеличиваться за пределы значения max_heap_table_size, которое по-прежнему действует как ограничение на максимальный размер таблицы. Для максимальной гибкости при использовании MAX_ROWS установите max_heap_table_size как минимум равным значению, до которого вы хотите, чтобы каждая таблица MEMORY могла увеличиваться.
Читайте также:
-
также относится к пакетной операционной аналитике.
Настоящая статья посвящена OLTP, а не Analytics. Информацию о том, как индексы columnstore переносят Google Analytics в SQL, см. в разделе:
Хранилище столбцов
Последовательность отличных сообщений в блогах элегантно объясняет индексы columnstore с нескольких точек зрения. В большинстве сообщений более подробно описывается концепция оперативной аналитики в реальном времени, которую поддерживает columnstore. Автор этих сообщений Сунил Агарвал, руководитель программы Microsoft, в марте 2016 г.
Операционная аналитика в реальном времени
Дефрагментация индекса columnstore
Массовый импорт данных
Возможности выполняющейся в памяти OLTP
Давайте рассмотрим основные функции In-Memory OLTP.
Таблицы, оптимизированные для памяти
Ключевое слово T-SQL MEMORY_OPTIMIZED в операторе CREATE TABLE указывает, как таблица создается для существования в активной памяти, а не на диске.
Таблицы, оптимизированные для памяти, имеют одно представление в активной памяти и вторичную копию на диске.
Модули, скомпилированные в собственном коде
Ключевое слово T-SQL NATIVE_COMPILATION в операторе CREATE PROCEDURE указывает, как создается хранимая процедура, скомпилированная в собственном коде. Операторы T-SQL компилируются в машинный код при первом использовании собственного процесса каждый раз, когда база данных циклически подключается к сети. Инструкции T-SQL больше не допускают медленной интерпретации каждой инструкции.
Собственный модуль может ссылаться только на таблицы, оптимизированные для памяти, и не может ссылаться на таблицы на диске.
Существует три типа модулей, скомпилированных в собственном коде:
-
.
Доступность в базе данных SQL Azure
In-Memory OLTP и Columnstore доступны в базе данных SQL Azure. Дополнительные сведения см. в разделе Оптимизация производительности с помощью технологий в памяти в базе данных SQL.
1. Убедитесь, что уровень совместимости >= 130
В этом разделе начинается последовательность пронумерованных разделов, которые вместе демонстрируют синтаксис Transact-SQL, который можно использовать для реализации функций In-Memory OLTP.
Во-первых, важно, чтобы для вашей базы данных был установлен уровень совместимости не ниже 130. Затем следует код T-SQL для просмотра текущего уровня совместимости, на который установлена ваша текущая база данных.
Далее идет код T-SQL для обновления уровня, если это необходимо.
2. Поднять уровень до SNAPSHOT
Когда транзакция включает как дисковую таблицу, так и таблицу, оптимизированную для памяти, мы называем это межконтейнерной транзакцией. В такой транзакции важно, чтобы часть транзакции, оптимизированная для памяти, работала на уровне изоляции транзакции с именем SNAPSHOT.
Чтобы обеспечить надежное применение этого уровня для таблиц, оптимизированных для памяти, в межконтейнерной транзакции, измените параметр базы данных, выполнив следующий T-SQL.
3. Создайте оптимизированную ФАЙЛОВУЮ ГРУППУ
В Microsoft SQL Server, прежде чем вы сможете создать оптимизированную для памяти таблицу, вы должны сначала создать FILEGROUP, которую вы объявляете CONTAINS MEMORY_OPTIMIZED_DATA. ФАЙЛОВАЯ ГРУППА назначается вашей базе данных. Подробнее см.:
В базе данных SQL Azure вам не нужно и нельзя создавать такую ФАЙЛОВУЮ ГРУППУ.
Следующий образец скрипта T-SQL включает базу данных для выполняющейся в памяти OLTP и настраивает все рекомендуемые параметры. Он работает как с SQL Server, так и с базой данных SQL Azure: enable-in-memory-oltp.sql.
Обратите внимание, что не все функции SQL Server поддерживаются для баз данных с файловой группой MEMORY_OPTIMIZED_DATA. Дополнительные сведения об ограничениях см. в разделе Неподдерживаемые функции SQL Server для In-Memory OLTP
4. Создайте оптимизированную для памяти таблицу
Ключевым ключевым словом Transact-SQL является ключевое слово MEMORY_OPTIMIZED.
Инструкции Transact-SQL INSERT и SELECT для таблицы, оптимизированной для памяти, такие же, как и для обычной таблицы.
ALTER TABLE для таблиц, оптимизированных для памяти
ИЗМЕНИТЬ ТАБЛИЦУ. ADD/DROP может добавить или удалить столбец из оптимизированной для памяти таблицы или индекса.
Планируйте таблицы и индексы, оптимизированные для памяти
5. Создайте хранимую процедуру, скомпилированную в собственном коде (native proc)
Ключевое ключевое слово — NATIVE_COMPILATION.
Ключевое слово SCHEMABINDING означает, что таблицы, на которые ссылается собственный процесс, не могут быть удалены, если сначала не будет удален собственный процесс. Подробнее см. в разделе Создание хранимых процедур, скомпилированных в собственном коде.
Обратите внимание, что вам не нужно создавать хранимую процедуру, скомпилированную в собственном коде, для доступа к таблице, оптимизированной для памяти. Вы также можете ссылаться на таблицы, оптимизированные для памяти, из традиционных хранимых процедур и специальных пакетов.
6. Выполнить собственный процесс
Заполните таблицу двумя строками данных.
За этим следует вызов EXECUTE хранимой процедуры, скомпилированной в собственном коде.
Вот фактический вывод PRINT:
Руководство по документации и дальнейшим действиям
Предыдущие простые примеры дают вам основу для изучения более сложных функций In-Memory OLTP. Следующие разделы представляют собой руководство по особым соображениям, которые вам могут понадобиться, и где вы можете увидеть подробную информацию о каждом из них.
Как функции In-Memory OLTP работают намного быстрее
В следующих подразделах кратко описывается внутренняя работа функций In-Memory OLTP для повышения производительности.
Как таблицы, оптимизированные для памяти, работают быстрее
Без блокировок. Таблица, оптимизированная для памяти, опирается на оптимистичный подход к конкурирующим целям целостности данных, параллелизма и высокой пропускной способности. Во время транзакции таблица не блокирует ни одну из версий обновленных строк данных. Это может значительно уменьшить конкуренцию в некоторых системах с большими объемами.
Версии строк. Вместо блокировок таблица, оптимизированная для памяти, добавляет новую версию обновленной строки в саму таблицу, а не в базу данных tempdb. Исходная строка сохраняется до тех пор, пока транзакция не будет зафиксирована. Во время транзакции другие процессы могут считывать исходную версию строки.
Меньше протоколирования: версии обновленных строк до и после хранятся в таблице, оптимизированной для памяти. Пара строк предоставляет большую часть информации, которая традиционно записывается в файл журнала. Это позволяет системе записывать в журнал меньше информации и реже. При этом обеспечивается целостность транзакций.
Как нативные процессы работают быстрее
Преобразование обычной интерпретируемой хранимой процедуры в скомпилированную хранимую процедуру значительно сокращает количество инструкций, выполняемых во время выполнения.
Компромиссы функций In-Memory
Как это принято в компьютерных науках, прирост производительности, обеспечиваемый функциями In-Memory, является компромиссом. Лучшие функции приносят преимущества, которые более ценны, чем дополнительные затраты на эту функцию. Полное руководство по компромиссным решениям можно найти по адресу:
В оставшейся части этого раздела перечислены некоторые основные аспекты планирования и компромиссы.
Компромиссы таблиц, оптимизированных для памяти
Оценка памяти. Вы должны оценить объем активной памяти, который будет потреблять ваша оптимизированная для памяти таблица. Ваша компьютерная система должна иметь достаточный объем памяти для размещения таблицы, оптимизированной для памяти. Подробнее см.:
Разбейте большую таблицу на разделы. Один из способов удовлетворить потребность в большом количестве активной памяти — разделить большую таблицу на части в памяти, в которых хранятся горячие последние строки данных, и другие части на диске, которые хранить холодные устаревшие строки (например, заказы на продажу, которые были полностью отправлены и выполнены). Это разбиение представляет собой ручной процесс проектирования и реализации. См.:
Компромиссы нативных процедур
Дополнительные сведения о таблицах, оптимизированных для памяти
Индексы для таблиц, оптимизированных для памяти, в некоторых отношениях отличаются от индексов для традиционных таблиц на диске. Хэш-индексы доступны только для таблиц, оптимизированных для памяти.
Вы должны спланировать наличие достаточного объема активной памяти для планируемой оптимизированной для памяти таблицы и ее индексов. См.:
Таблица, оптимизированная для памяти, может быть объявлена с параметром DURABILITY = SCHEMA_ONLY:
Табличные переменные также могут быть объявлены как оптимизированные для памяти. См.: