Spec-Zone.ru › MySQL 8.4

10.10.3 Кэширование подготовленных операторов и хранимых программ

Для некоторых операторов, которые клиент может выполнять несколько раз в течение сеанса, сервер преобразует оператор во внутреннюю структуру и кэширует эту структуру для использования во время выполнения. Кэширование позволяет серверу работать более эффективно, так как оно избегает накладных расходов на повторное преобразование оператора, если он потребуется снова в течение сеанса. Преобразование и кэширование выполняется для этих операторов:

  • Подготовленные операторы, как те, которые обрабатываются на уровне SQL (с помощью оператора PREPARE), так и те, которые обрабатываются с использованием двоичного протокола клиент/сервер (с помощью функции C API). Переменная системы max_prepared_stmt_count контролирует общее количество операторов, кэшируемых сервером. (Сумма количества подготовленных операторов во всех сеансах.)

  • Хранимые программы (хранимые процедуры и функции, триггеры и события). В этом случае сервер преобразует и кэширует весь тело программы. Переменная системы stored_program_cache указывает приблизительное количество хранимых программ, кэшируемых сервером на сеанс.

Сервер поддерживает кэши для подготовленных операторов и хранимых программ на основе каждого сеанса. Операторы, кэшированные для одного сеанса, недоступны для других сеансов. Когда сеанс завершается, сервер удаляет любые кэшированные для него операторы.

Когда сервер использует кэшированную внутреннюю структуру оператора, он должен позаботиться о том, чтобы структура не устарела. Изменения метаданных могут произойти для объекта, используемого оператором, что приведет к несоответствию между текущим определением объекта и определением, представленным во внутренней структуре оператора. Изменения метаданных происходят для операторов DDL, таких как те, которые создают, удаляют, изменяют, переименовывают или усекают таблицы, или анализируют, оптимизируют или восстанавливают таблицы. Изменения содержимого таблицы (например, с помощью оператора INSERT или UPDATE) не изменяют метаданные, как и операторы SELECT.

Вот иллюстрация проблемы. Предположим, что клиент подготавливает этот оператор:

PREPARE s1 FROM 'SELECT * FROM t1';

SELECT * расширяется во внутренней структуре до списка столбцов в таблице. Если набор столбцов в таблице изменяется с помощью ALTER TABLE, подготовленный оператор устаревает. Если сервер не обнаружит это изменение в следующий раз, когда клиент выполнит s1, подготовленный оператор вернёт некорректные результаты.

Чтобы избежать проблем, вызванных изменениями метаданных таблиц или представлений, на которые ссылается подготовленный оператор, сервер обнаруживает эти изменения и автоматически повторно подготавливает оператор при его следующем выполнении. То есть, сервер повторно анализирует оператор и восстанавливает внутреннюю структуру. Повторный анализ также происходит после того, как ссылающиеся таблицы или представления были удалены из кэша определений таблиц, либо неявно для освобождения места для новых записей в кэше, либо явно из-за FLUSH TABLES.

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

Сервер также обнаруживает изменения метаданных для объектов в выражениях. Они могут использоваться в операторах, специфичных для хранимых программ, таких как DECLARE CURSOR, или операторах управления потоком, таких как IF, CASE и RETURN.

Чтобы избежать повторного анализа всей хранимой программы, сервер повторно анализирует только затронутые операторы или выражения внутри программы по мере необходимости. Примеры:

  • Предположим, что метаданные для таблицы или представления изменены. Повторный анализ происходит для SELECT * в программе, которая обращается к таблице или представлению, но не для SELECT *, которая не обращается к таблице или представлению.

  • Когда оператор затронут, сервер повторно анализирует его только частично, если это возможно. Рассмотрим этот оператор CASE:

    CASE case_expr
      WHEN when_expr1 ...
      WHEN when_expr2 ...
      WHEN when_expr3 ...
      ...
    END CASE
    

    Если изменения метаданных затрагивают только WHEN when_expr3, это выражение переанализируется. case_expr и другие WHEN выражения не переанализируются.

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

Сервер пытается выполнить повторный анализ до трёх раз. Ошибка произойдёт, если все попытки завершатся неудачно.

Повторный анализ автоматический, но в той мере, в которой он происходит, снижает производительность подготовленных операторов и хранимых программ.

Для подготовленных операторов переменная состояния Com_stmt_reprepare отслеживает количество повторных приготовлений.

© 2025 Oracle
Licensed under the GPLv2 License.
https://docs.oracle.com/cd/E17952_01/mysql-8.4-en/statement-caching.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API