php кэширование запросов к бд

MySQL Query Cache

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

Использование кеша запросов полностью прозрачно для клиента. Клиент не знает о том, выполнил ли MySQL запрос, или вернул его из кеша.

MySQL кеширует результаты только SELECT запросов. MySQL не кеширует запросы, результаты которых могут измениться. Например, запросы в которых используются функции, относящиеся к текущему времени (NOW(), CURDATE() и др.), к текущему соединению (CURRENT_USER(), CONNECTION_ID() и др.) и другие. Полный список таких функций можно найти в мануале. Кроме этого, MySQL не кеширует запросы, в которых есть использование пользовательских функций, хранимых процедур, выборки из баз mysql или INFORMATION_SCHEMA, выборки из таблиц, для которых определены привилегии для столбцов.

Оптимизация для запросов, использующих функции текущего времени (NOW(), CURDATE() и др.) — замена таких функций на строку с датой. Например: запрос
SELECT * FROM table WHERE create_date > NOW() — INTERVAL 1 DAY
, который не будет кешироваться можно заменить на запрос, который закешируется:
SELECT * FROM table WHERE create_date > ‘2009-10-14’ — INTERVAL 1 DAY

Отдельно обрабатывается кеширование выборок от InnoDB таблиц. MySQL удаляет результаты выборок из кеша при любом изменении таблицы внутри транзакции (хотя мог бы не удалять до тех пор, пока транзакция не зафиксирована). Кроме этого, все выборки из этой таблицы не будут кешироваться до тех пор, пока транзакция не зафиксирована.

В момент начала записи MySQL не знает о размере получившейся выборки. Если записанный в кеш размер выборки больше, чем query_cache_limit, то запись прекращается и занятое место освобождается (поэтому, если вы знаете наперед, что результат выборки будет большим, рекомендуется выполнять его с директивой SQL_NO_CACHE). В случае, если MySQL кеширует несколько запросов параллельно, блоки, выделяемые для разных запросов, могут чередоваться. Кроме этого, после того, как запрос удален из кеша, освободившееся место может быть недостаточным для записи новых запросов. Это приводит к фрагментации кеша. Для дефрагментации кеша можно выполнить команду FLUSH QUERY CACHE. (FLUSH QUERY CACHE переносит все запросы, хранящиеся в кеше в его начало и помечает оставшуюся память как один свободный блок). Кроме этого уменьшить фрагментацию кеша можно правильным подбором параметра query_cache_min_res_unit.Если значение query_cache_min_res_unit небольшое, то фрагментация будет уменьшаться, однако, MySQL будет вынужден создавать больше блоков в кеше. Если значение велико, то фрагментация будет большой.

Значение query_cache_min_res_unit должно быть равно среднему размеру кешируемого значения. Его примерное значение можно вычислить по формуле query_cache_min_res_unit = (query_cache_size – Qcache_free_memory) / Qcache_queries_in_cache. Однако для сайтов, размер выборки которых сильно меняется, рекомендуется использовать query_cache_type = DEMAND и явное указание на то, что запрос должен быть закеширован директивой SQL_CACHE. Кроме этого, необходимо ограничить запись в кеш больших выборок заданием переменной query_cache_limit или директивой SQL_NO_CACHE.

Определить то, насколько фрагментирован кеш, можно по значению переменной Qcache_free_blocks. Для идеального нефрагментированного кеша значение равно единице, в худшем случае — Qcache_total_blocks / 2. Так же можно определить, что ваш кеш запросов сильно фрагментируется, если значение Qcache_lowmem_prunes постоянно возрастает при том, что значение Qcache_free_memory далеко от нуля.

Оценить эффективность использования кеша можно по формуле Qcache_hits / (Qcache_hits + Com_select). О том, какое значение является достаточным для вашего сайта решать вам. Если для запросов хранимых в кеше требуется большое время, то эффективность даже в 10% может быть полезной. Однако если эффективность использования низкая и увеличить ее не удается, то возможно, что характер нагрузки вашей системы такой, что кеш запросов вовсе не эффективен для вас. В таких случаях бывает более полезным вообще отключить кеширование запросов и использовать кеширование на стороне клиентов.

Читайте оригинал статьи на MySQL Consulting.

Источник

Php кэширование запросов к бд

В этом разделе помещены уроки по PHP скриптам, которые Вы сможете использовать на своих ресурсах.

Фильтрация данных с помощью zend-filter

Когда речь идёт о безопасности веб-сайта, то фраза «фильтруйте всё, экранируйте всё» всегда будет актуальна. Сегодня поговорим о фильтрации данных.

php кэширование запросов к бд. Смотреть фото php кэширование запросов к бд. Смотреть картинку php кэширование запросов к бд. Картинка про php кэширование запросов к бд. Фото php кэширование запросов к бд

Контекстное экранирование с помощью zend-escaper

Обеспечение безопасности веб-сайта — это не только защита от SQL инъекций, но и протекция от межсайтового скриптинга (XSS), межсайтовой подделки запросов (CSRF) и от других видов атак. В частности, вам нужно очень осторожно подходить к формированию HTML, CSS и JavaScript кода.

php кэширование запросов к бд. Смотреть фото php кэширование запросов к бд. Смотреть картинку php кэширование запросов к бд. Картинка про php кэширование запросов к бд. Фото php кэширование запросов к бд

Подключение Zend модулей к Expressive

Expressive 2 поддерживает возможность подключения других ZF компонент по специальной схеме. Не всем нравится данное решение. В этой статье мы расскажем как улучшили процесс подключение нескольких модулей.

php кэширование запросов к бд. Смотреть фото php кэширование запросов к бд. Смотреть картинку php кэширование запросов к бд. Картинка про php кэширование запросов к бд. Фото php кэширование запросов к бд

Совет: отправка информации в Google Analytics через API

Предположим, что вам необходимо отправить какую-то информацию в Google Analytics из серверного скрипта. Как это сделать. Ответ в этой заметке.

php кэширование запросов к бд. Смотреть фото php кэширование запросов к бд. Смотреть картинку php кэширование запросов к бд. Картинка про php кэширование запросов к бд. Фото php кэширование запросов к бд

Подборка PHP песочниц

Подборка из нескольких видов PHP песочниц. На некоторых вы в режиме online сможете потестить свой код, но есть так же решения, которые можно внедрить на свой сайт.

php кэширование запросов к бд. Смотреть фото php кэширование запросов к бд. Смотреть картинку php кэширование запросов к бд. Картинка про php кэширование запросов к бд. Фото php кэширование запросов к бд

Совет: активация отображения всех ошибок в PHP

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

php кэширование запросов к бд. Смотреть фото php кэширование запросов к бд. Смотреть картинку php кэширование запросов к бд. Картинка про php кэширование запросов к бд. Фото php кэширование запросов к бд

Агент

PHP парсер юзер агента с поддержкой Laravel, работающий на базе библиотеки Mobile Detect.

Источник

PHP Performance Series: Caching Techniques

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

Существует множество библиотек для такого кэширования, например, APC, XCache, eAccelerator и Zend Platform.

Кэширование промежуточного кода файлов
Когда у нас есть большое количество кода и наш сервис отличается большой посещаемостью, скорее всего мы не будем ждать, когда каждый PHP-файл будет обработан при его вызове, логично в этом случае запустить некий скрипт перед выкладкой кода на сервера, который сразу создаст промежуточный код. Например, код такого скрипта может быть реализован так

Кэширование переменных
Большинство библиотек кэширования позволяет кэшировать значения переменных. Очень полезно сохранять значения конфигурации или данные, которые сложно вычислить (получить) и которые не меняются (возможно не меняются в течение некоторого времени, тогда на базе такого кэширования можно реализовать кэширование с устареванием, примечание переводчика).

Concurrency Level: 5
Time taken for tests: 30.33144 seconds
Complete requests: 684
Failed requests: 0
Write errors: 0

Concurrency Level: 5
Time taken for tests: 30.12173 seconds
Complete requests: 709
Failed requests: 0
Write errors: 0

Как вы видите, мы получили около 3-4% в производительности, закэшировав значения конфигурационного файла. Существует много других мест, которые также можно оптимизировать, нахождение таких мест позволит увеличит количество обработанных запросов.

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

Полное кэширование вывода
Полное кэширование довольно тяжело выполнить на большинстве сайтов с постоянно обновляющимися данными из большого количества источников. Все это правда, однако, нет необходимости обновлять данные каждую секунду. Даже 5-10 минутная задержка при экстремально высокой загрузке сайта позволит вам увеличить производительность.
Пример ниже, сохраняет слепок страницы для будущего использования. Такой подход может помочь большому количеству пользователей.
Я не рекомендую использовать данное решение, но если вам нужно что-то быстрое, вы можете его использовать, рано или поздно вы увидите недостатки этого метода.
The Bootstrap Cache Example:

require(‘/path/to/pear/Cache/Lite/Output.php’);
$options = array(
‘cacheDir’ => ‘/tmp/’,
‘lifeTime’ => 10
);
$cache = new Cache_Lite_Output($options);
if (!($cache->start($_SERVER[‘REQUEST_URI’])))
<
require(‘/path/to/bootstrap.php’);
$cache->end();
>

.htaccess
php_value auto_prepend_file /path/to/cache_start.php
php_value auto_append_file /path/to/cache_end.php
cache_start.php
require(‘Cache/Lite/Output.php’);

$options = array(
‘cacheDir’ => ‘/tmp/’,
‘lifeTime’ => 10
);
$cache = new Cache_Lite_Output($options);
if (($cache->start($_SERVER[‘REQUEST_URI’])))
exit;

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

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

Кэширование в оперативной памяти
Существует множетсво путей для того чтобы произвести кэширование в памяти: memcached, memory tables в базах данных, RAM disk и другие.
Memcached
С сайта memcache memcached это высокопроизводительная и распределенная кэширующая система, которая увеличивает скорость динамических веб-приложений путём снижения загрузки с базы данных.
О чем это говорит, о том, что можно сохранить данные на одном сервере, к которому будут обращаться другие сервера, это не зависит от вашего веб-сервера (как в случае кеширования промежуточного кода), так как memcached – это демон, который в большинстве случаев используется для кэширования результатов запросов к базам данных.
Пример работы с Memcache:

session.save_handler = memcache
session.save_path = «tcp://hostname:11211»

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

Надеюсь, что описанное выше было достаточно информативно. Здесь не описан весь потенциал кэширования, например использование кэширования в распределенных базах данных или использование Squid. В будущих статьях я опишу и это…

Источник

Что использовать при кешировании запросов MySQL в PHP

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

Заранее благодарен за ответы!

У вас ложная информация по поводу главной причины, которая не дает Вам использовать нормальный вариант, но не это главное. Делайте таблицы-агрегаты. Посмотрите запросы и постройте индексы. Заполняйте их данными после перевода договоров в стабильные статусы. Если у вас есть лишняя оперативка — лучше отдать ее правильно спроектированной БД, чем скармливать бесполезному в этом случае мемкешу, например.
Договора заканчиваются, периоды закрываются, эти данные становятся статикой и хорошо берутся из агрегатов. Вариант с кешем хорош при частых обращениях к одинаковым данным. Ваши пользователи чаще загружают один и тот же договор, или смотрят последовательно разные? Наверняка последнее, а вы забьете оперативку договорами, которые уже не нужны пользователю. Повторюсь — лучше забить эту оперативку индексами.

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

php кэширование запросов к бд. Смотреть фото php кэширование запросов к бд. Смотреть картинку php кэширование запросов к бд. Картинка про php кэширование запросов к бд. Фото php кэширование запросов к бд

Одна из главных — сброс кеша при любом изменении таблицы — это критично, так как разрабатываемая система многопользовательская. Я уже задумывался, чтобы хранить результаты тяжелых запросов в файлах на сервере и при очередном выполнении запроса (с привязкой к пользователю системы) проверять, если уже такой запрос был, то брать из файла. Но в этом случае придется решать проблему именно отслеживания изменений в таблице.
— Получается немного нелогично. С одной стороны Вас беспокоит сброс кэша при любом изменении таблицы, с другой стороны Вы говорите что на кэш изменения в таблице влияют и их надо отслеживать.

Один из относительно легких вариантов для кэша, это memory таблица в mysql, куда складируются либо все данные которые часто выбираются либо ИД для их выбора из основных таблиц. Плюс по сравнению с 3rd-party решением тут то, что закэшить можно не прогоняя лишние данные через php и сеть, просто insert into select from — в большинстве случаев. Это во-первых. А во-вторых, триггерами при изменениях основной таблицы можно настроить апдейт кэширующей, более гибко чем просто тупой кэш запросов.
Ну и наконец если база относительно небольшая, то innodb + большой размер пула/кэша — тогда вообще все в памяти будет постоянно считай.

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

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

Источник

Нужно ли делать кеширование запросов и как?

Есть страница на сайте, которая работает по стандартном принципу:
1. Делаются несколько запросов к БД на выборку данных.
2. Результаты выборок передаются в шаблон который рендерится и на выходе получаем HTML.
3. Отдаем HTML пользователю.

При выполнении запросов к БД MySQL на выборку, происходит ли кеширование результатов автоматически на стороне самого MySQL?

Есть ли вообще смысл делать кеширование самому, учитывая то что возможно MySQL делает это и так (если делает конечно)?

Что лучше кешировать самому: результаты запросов (т.е. сериализовать массивы и класть их в Memcached) или весь отрендеренный HTML?

php кэширование запросов к бд. Смотреть фото php кэширование запросов к бд. Смотреть картинку php кэширование запросов к бд. Картинка про php кэширование запросов к бд. Фото php кэширование запросов к бд

Я думаю здесь подмена понятий. Автор пишет «кэширует ли БД запросы», а имеет в виду «может ли в принципе эта страшная и непонятная громадина которая называется базой данных в принципе хоть когда-нибудь рабтотать быстро?»
Все, разумеется, кидаются отвечать на первый вопрос.
А на самом деле надо отвечать на второй. Да, почти всегда БД работает гораздо быстрее чем ты можешь вообразить и ничего кэшировать не нужно. Если вдруг стало работать медленно. впрочем, об этом ниже.

php кэширование запросов к бд. Смотреть фото php кэширование запросов к бд. Смотреть картинку php кэширование запросов к бд. Картинка про php кэширование запросов к бд. Фото php кэширование запросов к бд

The query cache is deprecated as of MySQL 5.7.20, and is removed in MySQL 8.0.

если логика вашего приложения дает возможность кэшировать весь html с высокой эффективностью кэширования, то лучше это делать файловым кэшем на веб-сервере. если нет, то остается возможность кэшировать блоки страниц и собирать ее быстренько из кусочков, иногда даже с помощью Server Side Includes. в самом простом случае делают обертки над db-драйвером для кэширования результатов запросов.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *