Я немного озадачен тем, как оптимизировать мои запросы SQL. У меня есть средний сложный запрос с некоторыми объединениями, которые выполняются от ста до тысячи раз в секунду (две таблицы на SSD, одна таблица в оперативной памяти, 4 объединения)
Как я могу минимизировать накладные расходы на выполнение? Есть ли способ предварительно скомпилировать запрос, чтобы MySQL не нужно было анализировать, оптимизировать и компилировать запрос каждый раз?
Я знаю, что могу использовать подготовленный оператор для предварительной компиляции запроса, который затем выполняется несколько раз в одном сеансе. Но что делать, если у вас несколько сеансов и только один запрос на сеанс? Кешируются ли подготовленные операторы на разных сессиях Я так не думаю.
Тогда я подумал, что хранимые процедуры — лучший способ, потому что они, как говорят, предварительно скомпилированы. Сейчас я читаю, что это предположение совершенно неверно, они на самом деле не предкомпилированный.
Есть ли какой-нибудь способ поделиться клиентскими сессиями в MySQL, например? использовать подготовленные операторы в первом сеансе, унаследованном в следующих сеансах?
Последняя идея — написать многопоточный сервер сокетов, который будет действовать как клиент-прокси MySQL. Но это кажется мне немного преувеличенным. 😉
Я использую PHP в качестве модуля Apache2. Есть ли шанс «сохранить» сеанс MySQL в общей памяти, чтобы следующие HTTP-запросы могли использовать существующий сеанс MySQL вместо запуска нового? Чтобы я мог использовать подготовленные операторы для разных HTTP-запросов?
Q: Есть ли способ «повторно использовать» соединение MySQL, чтобы последующий запрос мог использовать существующее соединение?
A: Да. Вы можете использовать пул соединений реализация. Это знакомый шаблон с Java, с несколькими доступными реализациями.
Для реализации пула соединений в PHP вы можете использовать расширение PHP mysqldnd-ms
.
Ссылка: http://php.net/manual/en/mysqlnd-ms.pooling.php
ПРИМЕЧАНИЕ: у меня нет личного опыта с этим расширением PHP.
Некоторые из других вопросов, которые вы задали …
Q: Как я могу минимизировать накладные расходы на выполнение? Есть ли способ предварительно скомпилировать запрос, чтобы mysql не нужно было анализировать, оптимизировать и компилировать запрос каждый раз?
A: В MySQL 5.6 вы можете использовать серверную часть готовые заявления. План выполнения для подготовленного оператора кэшируется в сеансе, поэтому повторный вызов того же оператора SQL может повторно использовать ранее подготовленный план выполнения. (Эта функция недоступна в версиях MySQL до 5.6.)
Сокращение количества «перетаскивания соединений» ** сократит накладные расходы MySQL. Подключение и отключение от сервера базы данных — это работа, которую должен выполнить сервер. Достаточно просто проверить и сравнить производительность. В одном процессе откройте соединение и выполните несколько повторная работа (повторное выполнение простого заявления, как SELECT NOW()
, а затем отключите. В другом процессе запустите те же повторные выполнения SELECT, но подключайтесь и отключайтесь для каждого выполнения.
Q: Кешируются ли подготовленные операторы в разных сеансах?
A: Нет. Заявления кэшируются на заявление уровень сеанса
Q: Есть ли способ поделиться клиентскими сессиями в mysql, например? использовать подготовленные операторы в первом сеансе, унаследованном в следующих сеансах?
A: Нет. Единственный способ добиться этого — это не отключиться от базы данных и передать дескриптор этого сеанса следующему клиенту, который запрашивает соединение. И мы получаем это путем реализации пул соединений.
Я бы сказал, что одна из лучших практик для этого — избегать запросов и функций, основанных на времени O (n). Для того, чтобы хорошо выполнять данные при высокой нагрузке, все запросы должны быть в O (1) дополнительном времени. На самом деле это означает, что независимо от того, сколько данных вы выбираете, для запроса всегда будет требоваться одно и то же время. (Линейное уравнение)
Что я имею в виду, если вы храните IDS в $_SESSION
var, вы можете позже использовать его всякий раз, когда вам нужно сократить время запросов с O (n) до O (1).
Если вы увязли в чтениях, ведомые могут разрешить практически неограниченное масштабирование чтения.
Другие вопросы:
— Пакетные вставки очень помогают.
— InnoDB лучше при параллельном доступе.
— Задержка между странами может привести к задержкам, которые можно уменьшить с помощью хранимых процедур (и других методов).
— Как правило, запрашиваемые вами издержки менее важны, чем оптимизация запросов.
— ИП иногда помогают из-за меньшего времени ожидания.
— * Nix лучше, чем Windows.
— Слишком много «одновременных» соединений может быть контрпродуктивным.
— PHP-сессии вряд ли будут полезны.