Кэш sql где хранится

Обновлено: 29.06.2024

MySQL при работе с таблицами использует хорошо масштабируемые алгоритмы, так что MySQL может работать даже при малых объемах памяти. Естественно для лучшей производительности нужно больше оперативной памяти.

Для просмотра текущих настроек подключаемся к базе

Во-первых, убедимся, что кеширование включено. Переменная

  • query_cache_type должна иметь значение ON (1) или DEMAND (2) и
  • query_cache_limit – определяет максимальный размер результата который попадет в кэш
  • query_cache_size быть отличной от нуля. При использовании DEMAND кешироваться будут только запросы, в которых есть директива SQL_CACHE;
  • query_cache_min_res_unit минимальный размер выделяемого блока памяти для хранения результатов кешированного запроса. MySQL не хранит кеш в одном большом куске памяти, вместо этого по требованию выделяются блоки с минимальным размером query_cache_min_res_unit (=4KB по умолчанию). Последний такой блок обрезается до размера данных, а оставшаяся память освобождается.

Эффект кэширования в том что сервер получая запрос смотрит есть ли хэш запроса в кэше. Если хэш совпадает – сервер сразу отдает результат – не производя разбор запроса, оптимизацию и т.д. накладные расходы – в сопровождении механизма кэширования – просмотр кэша, запись результата запроса в кэш и т.д.

И если у вас много небольших запросов в кеше, то это может привести к фрагментации памяти из-за большого количества свободных блоков. А это, в свою очередь, вызывает удаление кешированных записей из-за недостатка памяти. В таком случае имеет смысл уменьшить значение query_cache_min_res_unit. Если большинство ваших запросов порождают большой результат, то увеличение этого параметра может повысить производительность.

Попробуем оценить эффект. Смотрим как меняются показания счетчиков попаданий в кэш (Qcahe_hits), количество запросов объявленных недействительными из-за нехватки памяти (Qcache_lowmem_prunes), общее количество запросов типа SELECT (а кэшируются только они). Делаем:

Для мониторинга query cache используется SHOW STATUS:

  • Qcache_free_blocks показывает сколько свободных блоков есть в кеше (будет уменьшаться по мере увеличения скэшированных запросов).;
  • Qcache_total_blocks — количество занятых блоков;
  • Qcache_free_memory — показывает свободную «доступную» память для кэширования;
  • Qcache_hits — количество запросов, результаты которых были взяты из кеша, без реального обращения к базе данных;
  • Qcache_inserts — количество запросов, которые были добавлены в кеш;
  • Qcache_lowmem_prunes — количество запросов, которые были удалены из кеша из-за нехватки памяти;
  • Qcache_not_cached — количество запросов, которые не были записаны в кеш из-за использования функций работы со временем и т.п.;
  • Qcache_queries_in_cache — количество запросов, которые находятся в кеше.

Можно просмотреть общее количество запросов SELECT:

Оценивать эффективность кэша рекомендуют делением значения переменной Qcache_hits на Qcache_hits + Com_select, поскольку при обработке запроса увеличивается счётчик Qcache_hits (если запрос обработан из кэша) или Com_select (если запрос не кэширован). Такой способ предлагают в «Mysql оптимизация производительности» O’reilly

В сети есть другой способ – qcache_hit_ratio = qcache_hits / (qcache_hits + qcache_inserts + qcache_not_cached)

Если это значение > 0.8, то значит 80% ваших запросов попадают в кэш, это очень хороший показатель.
Если % попадания в кэш низкий, то необходимо увеличить значение query_cache_size.

Текущее значение можно посмотреть так:

Опять же возникает вопрос: как выбрать адекватное значение query_cache_size?
В этом поможет Qcache_lowmem_prunes. В этой переменной хранится число запросов, которые были убраны из кэша из-за необходимости кэширования новых запросов. Необходимо стремится к такому размеру кэша, при котором Qcache_lowmem_prunes будет лишь незначительно увеличиваться. Для этого, рекомендуется сравнить разницу значений Qcache_lowmem_prunes за час и кол-во запросов, поступивших на mysql за этот же час.

На практике, для расчета query_cache_size можно использовать одну из 2-х формул:
query_cache_size = (число запросов за 10 минут)*(средний объем ответа на запрос) * 1,2
или
query_cache_size = (объем трафика за 10 минут) * 1,2

Это позволит закэшировать запросы на 10 минут + дать дополнительные 20% памяти на фрагментацию кэша и дополнительный резерв кэширования
Подсчитать количество и средний объем ответа на запроса можно использую переменные Bytes_sent соответственно

И так значения query_cache_size мы увеличили, после чего стоит обратить внимание на значения Qcache_total_blocks, Qcache_free_blocks и Qcache_queries_in_cache. MySQL хранит кэш в блоках. На 1 запрос необходимо 2 блока: один для самого текста запроса, второй для результата.
Если рассмотреть таблицу со значения Qcache%
Общее количество блоков кэша Qcache_total_blocks – 28
Закешировано сейчас 6 запрос, а значит занят 6*2 = 12 блоков
свободно блоков Qcache_free_blocks – 10. Чем больше незадействованных Qcache_free_blocks, тем больше степень “фрагментации” кэша.
Если большинство запросов имеют небольшой объем результирующих данных, то стоит уменьшить минимальный размер блока кэша query_cache_min_res_unit, который по умолчанию равен 4 Кб.
Если же большинство запросов возвращают много данных – то стоит увеличить размер блока кэша.
Главное – это добиться минимального значения Qcache_free_blocks.

Если счетчик Qcache_not_cached велик, можно попробоавть увеличить переменную query_cache_limit – она позволит увеличить лимит и помещать в кэш результаты запросов которые «не помещаются».

За использование кеша запросов отвечают следующие конфигурационные переменные:

Материал посвящен описанию использования подсистемы памяти в MS SQL server. Данный обзор дает только общее представление о структуре управления. Следует помнить, что продукты компании Microsoft поставляются с закрытыми кодами и детальные сведения отсутствуют в общедоступных источниках (насколько удалось выяснить нам, если Вам удалось большее – сообщите, пожалуйста). Общий обзор необходим для понимания описываемых далее возможных проблем SQL server и используемых средств тестирования и измерения производительности.

Memory manager


Memory manager (ММ) является основным элементом, который управляет распределением памяти в SQL сервере. Данный компонент автоматически распределяет доступную SQL серверу память, снижая необходимость ручной настройки. После загрузки SQL ММ определяет первоначальный объем распределенной памяти и далее по мере изменения нагрузки динамически резервирует или освобождает оперативную память. Таким образом, ММ управляет взаимодействием SQL сервера с операционной системы в контексте управления памятью. Memory manager является частью SQLOS. Подробнее можно посмотреть здесь.

Состав Memory Manager

Сведения о составе этого компонента весьма ограничены, однако можно выделить следующие составные части ММ: memory nodes, memory clerks (клерки памяти), memory caches (кэши) и memory objects (объекты). Подробнее можно прочитать здесь и здесь.

Также ММ предоставляет несколько счетчиков, которые позволяют оценить использование оперативной памяти в SQL. Подробнее можно прочитать здесь и здесь.

Обобщенно состав ММ представлен на Рисунке 1.1

image


Рисунок 1.1 Компоненты Memory Manager

Объекты ММ используются для распределения памяти внутри экземпляра SQL Server. Memory nodes обеспечивают интерфейс к ОС и реализацию выделения памяти на нижнем уровне. Внутри SQL Server только Memory clerks имеют доступ к интерфейсу. Memory nodes для распределения памяти. Каждый компонент SQL Sever, который потребляет существенный объем памяти должен создать собственный клерк и распределять память именно через его интерфейс.

Реализация управлению памятью меняется от версии к версии SQL, однако основные функциональные компоненты сохраняются. На рисунке 2.2 приведены отличия в реализации ММ в SQL2008 и SQL2012 дополнительные сведения можно найти здесь.

image


Рисунок 1.2 Изменения в структуре Memory Manager для SQL2008 и SQL 2012

Из рисунков видно, что полностью исчезло разделение page allocator. Эти компоненты были заменены одним Any-size page allocator.

Memory Nodes

Memory Nodes является внутренним объектом SQLOS. Представляет собой логический объект памяти, которая соответствует процессору в случае SMP-реализации или группе процессоров в случае NUMA-реализации. Подробнее можно посмотреть здесь.

image


Рисунок 1.3 Иерархия SQLOS в случае реализации SMP (А — рисунок) и NUMA (Б- рисунок)

Memory node абсолютно прозрачна для потребителей памяти. Главная задача этого компонента состоит в определении области выделения памяти. Memory node состоит из нескольких распределителей памяти (memory allocators). На рисунке 2.4 представлены потребители памяти, использующие memory node. Подробнее можно посмотреть здесь и здесь.

image


Рисунок 1.4 Memory nodes

Memory allocators являются процедурами, которые определяют тип Windows API используемой для выделения памяти. Аллокаторы содержат программный код используемый для выделения памяти, например, для страниц или использования shared memory.

Memory clerks

Memory nodes обеспечивают интерфейс к ОС и реализацию выделения памяти на уровне Windows. Внутри SQL Server только Memory clerks имеют доступ к интерфейсу Memory nodes для распределения памяти. Каждый компонент SQL Sever, который потребляет существенный объем памяти, должен создать собственный клерк и далее распределять ресурсы именно через его интерфейс.

Таким образом, клерки выполняют следующие функции в рамках Memory manager:
• Отражают использование памяти конкретными компонентами сервера
• Получают уведомления о смене состояний памяти и изменяют её размер согласно обстоятельствам.
• Используют Memory nodes для выделения памяти компонентам сервера.

Выделяют четыре категории клерков. Список категорий приведен в таблице 1. Подробнее можно посмотреть здесь.

Memory Caches

Под понятием «кэш» понимается механизм кэширования различных типов данных с учетом стоимости хранения объектов. Кэш обеспечивает: контроль времени хранения, видимость и анализ статистики обращения к кэшированным данным. Кэшированные данные могут быть использованы одновременно несколькими потребителями. Кроме кэшей SQL Server использует пулы памяти. Пулы в отличии от кэшей используются для хранения однородных данных без дополнительного контроля. Используется несколько механизмов кэширования и них основные:
• Cache Store
• User Store
• Object Store

Только Object Store является пулом, Cache и User Store являются кэшами. Механизмы Cache и User Store весьма похожи, однако если параметры Cache Store контролируются целиком SQLOS, то для User Store разработчики могут использовать собственные алгоритмы управления. В документации также используются понятия Cache Store и User Store со значением “обособленные области памяти”. Каждому Cache Store сопоставлено хранилище hash table. Возможно использование не одной, а нескольких таблиц hash tables. Hash table – это структура в памяти, которая содержит массив указателей на страницы буфера. Хэширование – это методика, которая единообразно отображает значение ключа в соответствующий hash bucket.
Подробнее можно прочитать здесь (про хэш) и здесь и здесь и здесь.

Cache Store используются, например, для хранения кэша планов выполнения, кэша xml, кэша полнотекстового поиска, Procedure Cache, System Rowset Cache. В User Store хранятся в частности кэш метаданных пользовательских и системных баз, токены безопасности, данные схем. Полный список можно найти в динамическом представлении dm_os_memory_cache_counters.

Buffer pool (buffer cache) а также buffer pool extension

Buffer pool (второе название buffer cache) – это область в памяти, которая используется для кэширования страниц, данных таблиц и их индексов, размер страниц 8Кб. Использования Buffer pool уменьшает ввод/вывод в файл базы данных и таким образом увеличивает производительность сервера. При этом Buffer Cach является основным потребителем памяти в SQL Server.

image


Рисунок 1.5 Компоненты системы управления буфером

В SQL Server 2014 buffer pool может быть расширен в энергонезависимую память, например, на диск SSD. Такое расширение называется Buffer Pool Extension. Подробнее можно прочитать здесь здесь.

Подробнее об управлении буферным кэшем можно прочитать здесь, здесь и здесь.

Буферный кэш имеет собственный клерк памяти и распределят память через page allocator. Для буферного кэша используется клерк памяти типа Generic и называется memoryclerk_sqlbufferpool.

До SQL 2012 Buffer Cache использовал только Single Page Allocator (распределяющий отдельные страницы 8Кб). Если компоненту сервера было необходимо выделить буфер большего, чем 8Кб размера использовался Multi Page Allocator (см. рис. 2.4) и соответственно эта память располагалась за пределами Buffer Pool. C SQL2012 Single и Multi Page allocators были объединены в Any-size page allocator. На рис. 2.2 можно увидеть эти изменения.

Max server memory и min server memory

Хотя управление буферным кэшем происходит автоматически внутри SQL Server, однако администраторы могут регулировать максимальный и минимальный размер распределяемой памяти для этого буфера.

image


Рисунок 1.6 Изменения в диапазоне памяти резервируемой параметром Max server memory

Как уже упоминалось в SQL 2012 произошли изменения memory manager. В результате таких изменений параметр max server memory регулирует не только память buffer pool, но вообще всё распределение памяти (кроме Direct Memory Allocations производимых с помощью VirtualAlloc).

Параметр min server memory обозначает границу, ниже которой Buffer Pool не будет по требованию освобождать занятую память. При первоначальной загрузке пул не занимает память, указанную в min server memory. Используется минимально необходимый объем, который вычисляется автоматически. Размер пула при необходимости в дальнейшем увеличивается.

Подробнее можно прочитать здесь и здесь.

Stolen pages

Stolen pages — это страницы буферного кэша, которые используются для различных целей в сервере. Например, для процедурного кэша, операций сортировки (т.е. рабочей памяти запроса — workplace memory). Также эти страницы необходимы для хранения таких структур данных, которые требуют распределение памяти менее 8Кб, например, блокировки, контекст транзакций и информации о соединении.

Подробнее можно посмотреть в следующих источниках:

Object Store

Object Store представляет собой пул памяти. Он используется для хранения однородных типов данных без дополнительного контроля стоимости хранения. Эти данные могут быть легко очищены в случае нехватки памяти. По своей структуре пулы являются клерками памяти (т.е. являются одним из его видов). Дополнительно можно посмотреть здесь и здесь.

Memory Objects (MO)

Memory Objects представляют собой кучу памяти, которая использует интерфейс клерков памяти чтобы получить доступ к page allocator для выделения страниц. Memory Objects не используют интерфейсы виртуальной или общей памяти, этот элемент использует только механизм распределения страниц. Многие компоненты SQL Server обращаются напрямую к MO, минуя клерки памяти. МО предоставляют возможность распределить диапазоны памяти произвольного размера.

Memory Broker (МВ)

Memory broker (брокер памяти) является компонентом SQLOS. Брокер памяти отвечает за распределение памяти между различными компонентами SQL Server в соответствии с их запросами. Более подробно можно прочитать на сайте производителя.

image


Рисунок 1.7 Распределение памяти Memory Broker

Описание механизма: МВ отслеживает запросы памяти от компонентов SQL и сопоставляет с текущими показатели её использования. Основываясь на полученной информации, брокер вычисляет «оптимальный» размер памяти, которая может быть распределена между компонентами. Брокер уведомляет компоненты о своих вычислениях, после этого каждый компонент использует эти сведения для дальнейшего использования памяти.

Oracle Result Cache -кэш результатов увеличивает скорость запросов SQL в базах данных Oracle

Улучшать время отклика (скорости исполнения) часто выполняемых SQL-запросов можно за счет использования кэша результатов. Кэш результатов сохраняет результаты SQL-запросов и PL/SQL -функций в новом компоненте SGA под названием Result Cache Memory (Память кэша результатов). При первом выполнении повторяющегося запроса база данных кэширует его результаты, а при последующих выполнениях — просто извлекает эти результаты из кэша результатов вместо того, чтобы выполнять запрос снова. В случае изменения любого из объектов, являющихся частью запроса, база данных делает находящиеся в кэше результаты этого запроса недействительными. Идеальными кандидатами на кэширование результатов являются запросы, которые предусматривают получение доступа к множеству строк для возврата всего лишь нескольких, как часто бывает во многих решениях типа хранилищ данных. Кэш результатов состоит из двух компонентов: SQL Query Result Cache (Кэш результатов SQL-запросов), в котором сохраняются результаты SQL-запросов, и PL/SQL Function Result Cache (Кэш результатов PL/SQL-функций), в котором сохраняются значения, возвращаемые PL/SQL-функциями, причем оба они используют одну и ту же инфраструктуру. О каждом из этих компонентов кэша результатов более подробно рассказывается в этой статье блога.

Настройка кэша результатов

Кэш результатов по умолчанию всегда включен, и его размер зависит от объема памяти, который база данных выделяет под разделяемый пул. В случае задания параметра MEMORY_TARGET для выделения памяти Oracle выделяет под кэш результатов 0,25% от значения этого параметра, а в случае задания параметра SGA_TARGET — 0,5% от его значения.

Выделяемый кэшу результатов объем памяти можно изменять установкой значения для параметра инициализации RESULT_CACHE_MAX_SIZE. Значение этого параметра может варьироваться от нуля до системного максимума. Установка нулевого значения, как показано ниже, приводит к отключению механизма кэширования результатов:

Поскольку по умолчанию механизм кэширования результатов включен, это означает, что и параметр RESULT_CAHCE_MAX_SIZE по умолчанию тоже имеет некое положительное значение, какое именно — зависит от значения параметра MEMORY_TARGET (или SGA_TARGET, если вместо этого используется такой параметр).

Помимо параметра RESULT_CACHE_MAX_SIZE, на функционирование кэша результатов оказывают воздействие еще два параметра: RESULT_CACHE_MAX_RESULT и RESULT_CACHE_REMOTE_EXPIRATION. Параметр RESULT_CACHE_MAX_RESULT указывает, сколько максимум места в кэше результатов может занимать один результат. По умолчанию один кэшируемый результат может занимать вплоть до 5% пространства кэша результатов, но в принципе можно разрешать занимать ему от 1% до 100%. Что касается параметра RESULT_CACHE_REMOTE_EXPIRATION, то он определяет, насколько долго находящийся в кэше результат, который зависит от удаленных объектов, должен оставаться действительным. По умолчанию этот параметр установлен в 0, т.е. использовать кэш результатов для запросов, в которых принимают участие удаленные объекты, нельзя. Объясняется это тем, что со временем удаленные объекты могут изменяться и, следовательно, приводить к превращению хранимых в кэше результатов в недействительные.

Установка значения для параметра RESULT_CACHE_MODE

То, будет база данных кэшировать результат запроса или нет, зависит от значения параметра инициализации RESULT_CACHE_MODE, который может принимать два значения: MANUAL или FORCE. Ниже приведено краткое описание того, как эти два значения воздействует на связанное с кэшированием результатов поведение в базе данных.

  • В случае установки для этого параметра значения FORCE база данных будет пытаться использовать кэш для всех результатов везде, где может. Этап помещения результатов в кэш, однако, в таком случае может пропускаться за счет включения в запрос подсказки NO_RESULT_CACHE.
  • В случае установки для этого параметра значения MANUAL база данных будет помещать результаты запроса в кэш только при условии наличия в запросе подсказки RESULT_CACHE.

По умолчанию для параметра RESULT_CACHE_MODE принимается значение MANUAL, и изменять его динамически можно так, как показано ниже:

Использование подсказок RESULT_CACHE и NO_RESULT_CACHE

Использование подсказки RESULT_CACHE в виде части запроса приводит к добавлению в план выполнения этого запроса операции ResultCache. Эта операция ResultCache будет просматривать кэш результатов для выяснения того, не хранится ли в нем результат для данного запроса. Если таковой в кэше имеется, она будет извлекать его, а если нет, тогда будет выполнять запрос и сохранять его результаты в кэше результатов. Подсказка no_result_cache работает противоположным образом. При добавлении ее в запрос она будет заставлять операцию ResultCache обходить кэш результатов и выполнять запрос заново.

Ниже приведен пример включения в SQL-запрос подсказки RESULT_CACHE:

В этом примере подсказка RESULT_CACHE в первой строке запроса указывает, что должна использоваться операция ResultCache, проверяющая кэш результатов на предмет наличия в нем готовых результатов данного запроса и, если таковых там нет, выполняющая запрос и сохраняющая его результаты в кэше. Вывод EXPLAIN PLAN для этого запроса показывает, что для него используется кэш результатов:

Совет. Подсказки RESULT_CACHE и NO_RESULT_CACHE всегда превосходят по важности значение, установленное для параметра инициализации RESULT_CACHE_MODE.

Вывод EXPLAIN PLAN выявляет использование кэша результатов для запроса в данном примере. Раз для использования кэша результатов пришлось применять подсказку RESULT_CACHE, значит, для параметра RESULT_CACHE_MODE установлено значение MANUAL. В случае установки для него значения FORCE добавлять подсказку RESULT_CACHE в запросы не понадобится. База данных будет просто кэшировать результаты всех повторяющихся SQL- операторов, если только в них не будет присутствовать подсказка NO_RESULT_CACHE.

Oracle Result Cache - кэш результатов ускоряет запросы SQL в базе данных Oracle

Управление кэшем результатов

Для управления кэшем результатов, например, для проверки его состояния или сбрасывания его содержимого, служит пакет DBMS_RESULT_CACHE. Ниже приведен пример проверки объема выделяемой кэшу памяти за счет выполнения такой функции из этого пакета, как MEMORY_REPORT:

С помощью функции STATUS можно проверять текущее состояние кэша результатов, каковое может выглядеть как ENABLED или DISABLED. Очищается кэш результатов посредством процедуры или функции FLUSH. Необходимость в очистке кэша результатов может возникать в случае его полного заполнения базой данных, поскольку автоматически сброс его содержимого не происходит. При загрузке новой версии функции, например, может быть удобно избавиться от результатов старой функции в кэше, удалив их с помощью процедуры или функции FLUSH. Перед выполнением процедуры или функции FLUSH, однако, нужно обязательно перевести кэш результатов в обходной режим, запустив процедуру BYPASS со значением TRUE. После очистки кэша результатов нужно выполнить процедуру BYPASS снова, но на этот раз со значением FALSE, как показано ниже:

Ниже перечислены представления, которые можно использовать для управления кэшем результатов.

  • V$RESULT_CACHE_STATISTICS. Это представление отображает перечень настроек кэша и статистические данные по используемой им памяти.
  • V$RESULT_CACHE_OBJECTS. Это представление отображает список всех находящихся в кэше объектов и их атрибутов.
  • V$RESULT_CACHE_DEPENDENCY. Это представление отображает информацию о зависимостях между находящимися в кэше результатами и объектами, от которых они зависят.
  • V$RESULT_CACHE_MEMORY. Это представление отображает список всех используемых кэшем блоков памяти и статистические данные по ним.
  • V$RESULT_CACHE_OBJECTS. Это представление отображает список как всех находящихся в кэше результатов, так и их зависимостей.

Например, для выяснения того, какие результаты находятся в кэше результатов, можно воспользоваться следующим запросом к представлению V$RESULT_CACHE_OBJECTS:

Вывод приведенного выше запроса показывает, что в текущий момент в кэше результатов находятся два результата.

Ограничения по использованию кэша результатов SQL-запросов

Ниже перечислены объекты, для которых нельзя помещать результаты в кэш результатов SQL-запросов (SQL Query Result Cache):

  • временные таблицы;
  • таблицы словаря данных;
  • недетерминированные функции PL/SQL;
  • псевдофункции curval и nextval;
  • функции SYSDATE, SYS_TIMESTAMP, CURRENT_DATE, CURRENT_TIMESTAMP, LOCAL_TIMESTAMP, USERENV, SYS_CONTEXT и SYS_QUID.

Кроме того, в кэш нельзя помещать результаты подзапросов, но для них можно использовать подсказку RESULT_CACHE во вложенном представлении.

Компонент PL/SQL Function Result Cache

Компонент SQL Query Result Cache (Кэш результатов SQL-запросов) разделяет инфраструктуру кэша результатов с компонентом PL/SQL Function Result Cache (Кэш результатов PL/SQL-функций), который кэширует результаты PL/SQL-функций. Кандидатами на помещение в кэш результатов PL/SQL-функций являются те функции, которые используются в базе данных часто и зависят от относительно статической информации. При желании можно указать, что база данных должна делать находящиеся в кэше результаты PL/SQL-функции недействительными в случае внесения изменений в любой из объектов, от которых эта функция зависит.

Создание кэшируемой функции

Заставить базу данных помещать результаты функции в кэш PL/SQL Function Result Cache можно, включив в определение PL/SQL-функции конструкцию RESULT_CACHE, например, так:

Конструкция RELIES_ON является необязательной. Она указывает, что база данных должна делать результаты функции в кэше недействительными в случае подвергания любой из таблиц или других объектов, от которых эта функции зависит, какому-нибудь изменению. При первом выполнении функции GET_DEPT_INFO базой данных она будет выполняться обычным образом. При последующих же выполнениях этой функции база данных будет извлекать ее значения прямо из кэша PL/SQL Result Function Cache вместо того, чтобы выполнять ее заново. Выполнять функции заново база данных будет только в следующих случаях.

  • В случае обхода кэша результатов за счет не указания подсказки RESULT_CACHE.
  • В случае выполнения процедуры DBMS_RESULT_CACHE_BYPASS для вынуждения функций и запросов обходить кэш результатов, независимо от значения параметра RESULT_CACHE_MODE или указания подсказки RESULT_CACHE.
  • В случае изменения любого из лежащих в основе функции объектов и указания конструкции RELIES_ON в ее определении.
  • В случае удаления находящихся в кэше результатов базой данных из-за того, что система нуждается в дополнительной памяти.

Ограничения

Для того чтобы база данных помещала результаты PL/SQL-функции в кэш, эта функция должна удовлетворять следующим требованиям:

  • не содержать никаких параметров IN/OUT;
  • не представлять собой анонимный блок;
  • не определяться в модуле, который обладает правами вызывающего (invoker rights);
  • не содержать параметров типа коллекций, объектного типа, типа REF CURSOR или LOB;
  • не представлять собой конвейерную табличную функцию.

Помимо соблюдения этих требований, функция еще не должна зависеть ни от каких специфических параметров сеансов или контекстов приложений, а также не иметь побочных эффектов.

Компонент Client Query Result Cache

В отличие от механизма кэширования на стороне сервера, механизм кэширования на стороне клиентов по умолчанию не включен. Если приложения производят небольшие наборы результатов, которые остаются статическими на протяжении какого-то времени, реализация механизма кэширования на стороне клиентов может оказаться довольно выгодным решением. Часто выполняемые запросы и запросы, задействующие справочные таблицы (lookup tables), тоже могут являться хорошими кандидатами на кэширование на стороне клиентов.

Включение и отключение компонента Client Query Result Cache

Как и для механизма кэширования на стороне сервера, для включения и отключения механизма кэширования на стороне клиентов применяется параметр инициализации RESULT_CACHE_MODE. Подсказки RESULT_CACHE и NO_RESULT_CACHE тоже работают тем же самым образом, что и при выполнении кэширования на стороне сервера. В случае указания значения MANUAL для параметра RESULT_CACHE_MODE, для того, чтобы результаты запроса кэшировались, нужно обязательно включить в него подсказку RESULT_CACHE. Кроме того, как и в случае кэширования на стороне сервера, обе эти подсказки переопределяют значение параметра RESULT_CACHE_MODE. Передавать подсказки RESULT_CACHE и NO_RESULT_CACHE операторам SQL, правда, нужно с помощью вызовов OCIStatementPrepare() и OCIStatementPrepare2().

Управление компонентом Client Query Result Cache

Управлять тем, как работает компонент Client Query Result Cache, позволяют два параметра. Ниже приведено их краткое описание.

  • CLIENT_RESULT_CACHE_SIZE. Этот параметр позволяет задавать максимальный размер клиентского кэша наборов результатов для каждого процесса (в байтах). Установка для него нулевого значения приводит к отключению Client Query Result Cache. По умолчанию база данных выделяет каждому клиентскому процессу OCI максимальный объем памяти.

Совет. Значение параметра CLIENT_RESULT_CACHE_SIZE можно переопределять с помощью серверного параметра OCI_RESULT_CACHE_MAX_SIZE. Например, установкой для него нулевого значения можно полностью отключить компонент Client Query Result Cache.

  • CLIENT_RESULT_CACHE_LAG. Этот параметр позволяет задавать для Client Query Result Cache время запаздывания (lag time). Установка для него низкого значения ведет к увеличению количества круговых обращений из библиотеки клиента OCI к базе данных. Поэтому задавать для него низкое значение стоит только в том случае, если приложение получает доступ к базе данных нечасто.

Еще есть необязательный клиентский конфигурационный файл, который переопределяет любые из касающихся кэширования на стороне клиента параметров, которые устанавливаются на сервере. Называется он sqlnet.ora, и в нем можно устанавливать следующие конфигурационные параметры на стороне клиента.

  • OCI_RESULT_CACHE_MAX_SIZE. Этот параметр позволяет указывать максимальный размер кэша запросов для одного процесса.
  • OCI_RESULT_CACHE_MAX_RSET_SIZE. Этот параметр позволяет задавать максимальный размер одного результата в байтах для одного процесса.
  • OCI_RESULT_CACHE_MAX_RST_ROWS. Этот параметр позволяет указывать максимальный размер результата запроса в строках для одного процесса.

Также в приложениях OCI можно применять подсказки RESULT_CACHE и NO_RESULT_CACHE. С помощью представления CLIENT_RESULT_CACHE можно просматривать параметры кэша результатов и статистику использования Client Query Result Cache.

Ограничения

Ниже перечислены запросы, результаты которых нельзя помещать в кэш на стороне клиенте, хотя их возможно помещать в кэш результатов на стороне сервера:

Нам нравится думать, что SQL Server использует всю нашу память для кэширования данных, но это лишь часть правды. SQL Server использует память для многих вещей:

  • Кэширование объектов базы данных
  • Сортировка данных для результатов запроса
  • Планирование выполнения кэширования
  • Выполнение системных задач

Часто мы удивляемся тому, как мало данных кэшируется для каждой базы данных.

На прошлой неделе мы просмотрели 8KB страницы в нашей базе данных. Эти страницы одинаковы независимо от того, находятся ли они на диске или в памяти - они включают в себя идентификатор базы данных и идентификатор объекта, поэтому, если мы посмотрим на все страницы в памяти, мы можем выяснить, какие таблицы кэшируются в памяти прямо сейчас. Следующий запрос дает нам волшебные ответы, но имейте в виду, что чем больше у вас памяти, тем больше времени это займет. Он не будет блокировать других пользователей, но это может занять минуту или две, если у вас >64 ГБ памяти, несколько минут, если у вас есть терабайт или больше:

SELECT CAST(COUNT(*) * 8 / 1024.0 AS NUMERIC(10, 2)) AS CachedDataMB ,

CASE database_id WHEN 32767 THEN 'ResourceDb' ELSE DB_NAME(database_id) END AS DatabaseName

GROUP BY DB_NAME(database_id) , database_id

ORDER BY 1 DESC

Это ведет нас к интересным вопросам

Этот DMV-запрос ведет к множеству вопросов о настройке производительности!

Как быстро меняются кэшированные страницы? С того момента, как мы прочитали страницу размером 8КБ, сколько времени она остается в памяти, прежде чем мы должны будем удалить ее из кеша для того, чтобы освободить место для чего-то еще, что мы читаем с диска? Эта концепция - ожидание страницы Page Life, счетчик Perfmon, который измеряет в секундах, сколько времени что-либо остается в оперативной памяти. Чем дольше, тем лучше.

Изменяются ли результаты в зависимости от времени суток? Это моментальный снимок того, что находится в памяти на данный момент, но он может измениться в одно мгновение. Если у вас есть автоматизированные процессы, которые запускают несколько отчетов в одной базе данных в 2 часа ночи, тогда картина памяти будет выглядеть совершенно иначе.

Мы кэшируем малоценные данные? Если вы смешиваете приложения поставщиков и собственные приложения на сервере, вы часто можете обнаружить, что самое плохо написанное приложение будет использовать большую часть памяти. Дело в том, что это может быть не самое важное приложение. К сожалению, у нас нет способа ограничить объем памяти, используемый каждой базой данных. Именно поэтому большинство магазинов предпочитают запускать приложения-вендоры на отдельных виртуальных машинах или серверах - таким образом, они не выводят всю память на SQL Server, которая должна обслуживать другие приложения.

У нас достаточно памяти? Если вы используете SQL Server 2008 / R2 / 12 Standard Edition, вы ограничены только 64 ГБ физической оперативной памяти. Если вы используете SQL Server на голом железе (а не на виртуальной машине) и у вас меньше 64 ГБ, покупайте еще, чтобы добраться до отметки в 64 ГБ. Это самое безопасное и простое изменение настроек производительности, которое вы можете сделать. Если вы работаете на виртуальной машине или работаете с Enterprise Edition, вопрос с памятью усложняется. Чтобы узнать больше, прочитайте A Sysadmin's Guide to SQL Server Memory .

Используем ли мы память для чего-либо другого, кроме SQL Server? Если у нас есть Integration Services, Analysis Services, Reporting Services или любые другие приложения, установленные на нашем сервере, это лишает нас драгоценной памяти, которая нам может понадобиться для кэширования данных. Не запускайте SSMS - это пожиратель памяти. Поместите свои средства управления на виртуальную машину в центре обработки данных и удаленный рабочий стол вместо этого.

Можем ли мы уменьшить потребность в памяти с помощью индексов? Если у нас есть действительно широкая таблица (много полей) или действительно широкий индекс, и мы не запрашиваем активно большинство этих полей, то мы кэшируем целую кучу данных, которые нам не нужны. Помните, SQL Server кэширует на уровне страницы, а не на уровне поля. Некластерный индекс - это более узкая копия таблицы с нужными нам полями / столбцами. Чем меньше полей, тем больше данных мы можем упаковать на страницу. Чем больше мы можем упаковать, тем больше данных мы кэшируем.

Читайте также: