MySQL кеширует подготовленные операторы для производительности

0

mysql_stmt_close заявления не кэшируются MySQL, если вы вызываете mysql_stmt_close?

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

Например, было бы лучше висеть на указателе mysql_stmt и просто постоянно связывать разные параметры и выполнять его?

Или это только сохранит мне выделение памяти C, потому что MySQL фактически кэширует утверждения на основе соответствия запросов (или что-то еще), и это не имеет никакого отношения к тому, сколько раз я mysql_stmt_prepare и mysql_stmt_close или сколько раз я mysql_connect?

Теги:
prepared-statement

1 ответ

2
Лучший ответ

Если вы выдаете подготовленный оператор, MySQL подготавливает некоторые вещи, такие как планы синтаксического анализа и исполнения, поэтому, когда вы позже связываете фактические параметры, это не нужно делать (снова). Обычно для подготовки требуется только несколько мс. Если это релевантно будет зависеть от общего времени выполнения вашего запроса, и вы можете сэкономить только время, если вы запустите его более одного раза (но вы не теряете время, если вы просто запустите его один раз). При этом использование подготовленных операторов, даже если вы просто запускаете его один раз, является стандартной мерой безопасности.

Готовый оператор хранится на сервере и требует (немного) памяти. Он освобождается, когда вы закрываете его и не кэшируется впоследствии. Это также относится к соединению, поэтому разные соединения будут выделять собственную память для одного и того же запроса.

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

Имеются некоторые практические последствия при проведении долговременных подготовленных заявлений, причем наиболее важные из-за того, что подготовленные заявления теряются, когда вы теряете соединение (либо случайно, либо если вы его намеренно закрываете). Это может или не может усложнить ваш код (например, повторная инициализация ваших заявлений о потере соединения). Это также заставляет вас держать ваше соединение открытым, и хотя MySQL обычно не нуждается в большом количестве ресурсов, чтобы спальное соединение было открытым, вы можете или не захотите этого. Кроме того, это в основном помешает вам использовать пулы соединений (если они не поддерживают это), поскольку вы не можете дать соединение обратно в пул, не теряя подготовленный оператор (хотя это обычно менее актуально для c-приложения).

Это поведение стандартного c mysql api (как предложил ваш синтаксис). Если вы используете альтернативные инструменты, это может, конечно, быть другим. Например, java-драйвер делает (необязательно) кеширование операторов на .close. Но это в основном делает это, просто не закрывая его (через api), и обрабатывая такие вещи, как повторная инициализация потери соединения и так внутренне. Это подразумевает, что может быть какое-то использование для такого кеша (стороны приложения), и, хотя я не знаю альтернативы для этого, безусловно, возможно (и не должно быть сложно) реализовать это (и, вероятно, кто-то уже сделал это).

И последнее примечание, поскольку вы, возможно, ищите это: до MySQL 8 был кеш запроса, чтобы кэшировать результат конкретного SQL-запроса. Если вы дважды запускаете запрос с одним и тем же кодом (с теми же параметрами), и если не было никаких обновлений для таблиц (и если кеш был включен и набор результатов не был слишком большим), MySQL будет получать результат из этот кеш без необходимости повторного запроса запроса. Он только тесно связан с подготовленными заявлениями и прозрачен для приложения (вам не нужно ничего менять), но может быть актуальным в контексте кеширования.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню