Mysql не использовать кэш
ProxySQL – это прокси-сервер с поддержкой SQL, который может служить связующим звеном между приложением и базой данных. Он предлагает множество функций, таких как распределение нагрузки между несколькими серверами MySQL и кэширование запросов. В этом мануале основное внимание будет уделено кэшированию ProxySQL и тому, как с его помощью можно оптимизировать запросы базы данных MySQL.
Кэширование MySQL происходит следующим образом: при отправке запроса результат сохраняется в кэше, и если этот запрос повторяется позже, результат можно просто извлечь из кэша, не обращаясь к базе данных. Это может значительно увеличить скорость обработки общих запросов. Но многие средства кэширования требуют внесения изменений в код приложения, что может привести к ошибке. К счастью, ProxySQL позволяет избежать редактирования кода благодаря поддержке прозрачного кэширования.
При прозрачном кэшировании изменять конфигурацию ProxySQL нужно только администраторам баз данных: они включают кэширование наиболее распространенных запросов. Эти изменения можно внести через интерфейс администратора ProxySQL. Все, что нужно сделать разработчику, – это подключиться к прокси-серверу, поддерживающему протокол, и прокси-сервер сам решит, можно ли обработать запрос из кэша, не обращаясь к внутреннему серверу.
В этом мануале мы покажем, как использовать ProxySQL для настройки прозрачного кэширования MySQL в Ubuntu 16.04. Затем мы протестируем производительность сервера с кэшированием и без, используя инструмент mysqlslap, чтобы вы увидели, сколько времени можно сэкономить.
Альтернативные способы кэширования
Несмотря на то, что встроенный кэш запросов представляет мощный и ясный механизм, в ряде случаев он неприменим. Опишем наиболее распространенные:
- Запрос использует пользовательские функции, но тем не менее является детерменистическим.
- Оптимизация работы подзапросов потребовала разбить запрос на два с использованием временных таблиц.
- Таблица часто обновляется, аннулируя кэш, но не обязательно делать актуальную выборку.
- В таблице часто обновляются поля, не использованные в запросе (что все равно аннулирует кэш запросов к данной таблице).
Предположим, таблица часто обноваляется, но нам достаточно обновлять информацию на главной раз в минуту. Мы приведем простой способ ручного кэширования запроса с помощью MEMORY-таблицы. Если результат, хранящийся в MEMORY-таблице старше одной минуты, будем выполнять запрос и заносить результат в MEMORY-таблицу.
Первое, проверим существует ли таблица с кэшированным результатом не старше одной минуты:
Анализируем значение fresh в полученной строке. Если fresh=0 или произошла ошибка, значит запрос следует выполнить и внести в MEMORY-таблицу:
DROP TABLE IF EXISTS 'cache_mainpage_query' ;
CREATE TABLE cache_mainpage_query ENGINE = MEMORY
SELECT now ( ) AS create_time, . FROM . WHERE . ORDER BY . LIMIT . ;
Затем, как в случае c=0, так и в случае c=1, выполняем запрос и возвращаем результат клиенту:
Замечание. В рассмотренном примере время создания таблицы заносится в каждую строчку временной таблицы (колонка create_time). Это неэффективно по занимаемому месту в памяти, поэтому если объем памяти станет узким местом, следует перенести время кэширования в отдельную таблицу.
Если правило сортировки сложное (например, требует подключения дополнительных таблиц или вычислений над полями), то сортировка кэшированного запроса займет время. Чтобы этого избежать, пронумеруем строки при выполнении основного запроса:
SET @c:= 0 ;
CREATE TABLE cache_mainpage_query ENGINE = MEMORY
SELECT now ( ) AS create_time, @c:=@c +1 AS ord , . FROM . WHERE . ORDER BY . LIMIT . ;
Выборка в этом случае упрощается:
С MEMORY-таблицами связано одно ограничение: в таких таблицах нельзя хранить поля типа BLOB/TEXT. Если Вам требуется хранить поля такого типа, можно либо создать MEMORY-таблицу явно с полями типа varchar() длиной до 65535 символов, либо использовать таблицы типа MyISAM.
Мы рассмотрели далеко не все варианты альтернативного кэширования, например, за кадром оказалось кэширование с помощью memcached и кэширование готовых кусков HTML. Напишите в комментариях, какие темы из области оптимизации производительности MySQL вам интересны.
Статья написана по материалам онлайн-курса «Оптимизация производительности MySQL».
Отличная подробная статья, автору респект!
Пара вопросов:
1) Какой реальный выйгрыш дает кэширование результата запросов, хотя бы в относительных величинах, т.к. в абсолютных, как я понимаю, всё зависит от нагруженности сервера, сложности запроса и др. факторов.
2) Не слишком ли сложна схема с MEMORY-таблицами? Неужели отдача от MEMORY-таблицы (хоть и готового результата) настолько быстрее, чем отдача некешированного результата от MyISAM-таблицы?
2. Схема абсолютно простая. Дело в том, что MEMORY-таблица создается раз в минуту или раз в пять минут, а выборка из нее происходит мгновенно. Исходная задача - мы имеем сложнейший запрос, который связывает несколько таблиц, сортирует (с подзапросами и.т.д.), чтобы сформировать десятку лучших статей или что-нибудь еще простое, но то, что формируется сложным алгоритмом. Такие запросы могут выполняться секунды, а мы имеем несколько обращений к серверу в секунду - сервер висит. Если бы работал кэш, то запрос бы выполнялся быстро, но кэш не работает из-за непрерывных апдейтов к таблице (на webew это конечно не так, но много есть примеров). MEMORY-таблицу мы создаем раз в минуту - это занимает несколько секунд, но зато выборка из нее совершается мгновенно. В итоге, сложный запрос выполняется раз в минуту, а не несколько раз в секунду.
P.S. рекомендую смотреть не на длину SQL-запроса, а на время его выполнения и частоту выполнения. Необходимо учесть, что в таких запросах обычно ORDER BY + LIMIT (о чем я собираюсь написать отдельную статью скоро), то есть сортируется вся таблица - тысячи записей, а итог - десяток записей. Например, чтобы выбрать 10 лучших статей, нужно сложить все голоса за каждую из статей, затем отсортировать весь список по убыванию балла и только потом выбрать первые 10.
Спасибо за статью!
Кстати, насчет кэширования в memory таблицах: Вы в курсе, что запрос вида
I'm testing the speed of some queries in MySQL. The database is caching these queries making it difficult for me to get reliable results when testing how fast these queries are.
Is there a way to disable caching for a query?
System: MySQL 4 on Linux webhosting, I have access to PHPMyAdmin.
4: Настройка кэша запросов
Сейчас у нас есть тестовая БД, где мы уже запустили SELECT при отключенном кэше запросов. Давайте теперь включим этот кэш, отредактировав конфигурационный файл MySQL.
Откройте файл в редакторе:
sudo nano /etc/mysql/my.cnf
Добавьте следующие строки в конец файла:
.
[mysqld] query_cache_type=1
query_cache_size = 10M
query_cache_limit=256K
Мы включили кэш запросов, установив для параметра query_cache_type значение 1. Также мы установили индивидуальный предельный размер запроса в 256 КБ и выделили 10 мегабайт для кэша запросов (значение параметра query_cache_size равно 10 МБ).
Сохраните и закройте файл. Затем перезапустите сервер MySQL, чтобы изменения вступили в силу:
sudo systemctl restart mysql
Итак, мы включили кэш запросов. Давайте посмотрим, как изменится производительность при обработке того же запроса.
Требования
- Сервер Ubuntu 18.04, настроенный по этому мануалу.
- Сервер MySQL (смотрите мануал Установка MySQL в Ubuntu 18.04).
3: Тестирование MySQL без кэша запросов
Цель этого мануала – оптимизировать сервер MySQL с помощью кэширования запросов. Чтобы увидеть разницу в скорости, мы оценим производительность обработки запросов до и после внедрения кэша.
Сейчас мы создадим тестовую БД и вставим туда какие-нибудь данные, чтобы посмотреть, как MySQL работает без кэша запросов.
Создайте базу данных и назовите ее sample_db, выполнив следующую команду:
Create database sample_db;
Query OK, 1 row affected (0.00 sec)
Перейдите в эту БД:
Use sample_db;
Database changed
Создайте здесь таблицу с двумя столбцами, customer_id и customer_name. Давайте назовем таблицу customers:
Create table customers (customer_id INT PRIMARY KEY, customer_name VARCHAR(50) NOT NULL) Engine = InnoDB;
Query OK, 0 rows affected (0.01 sec)
Запустите следующие команды, чтобы вставить тестовые данные:
Insert into customers(customer_id, customer_name) values ('1', 'JANE DOE');
Insert into customers(customer_id, customer_name) values ('2', 'JANIE DOE');
Insert into customers(customer_id, customer_name) values ('3', 'JOHN ROE');
Insert into customers(customer_id, customer_name) values ('4', 'MARY ROE');
Insert into customers(customer_id, customer_name) values ('5', 'RICHARD ROE');
Insert into customers(customer_id, customer_name) values ('6', 'JOHNNY DOE');
Insert into customers(customer_id, customer_name) values ('7', 'JOHN SMITH');
Insert into customers(customer_id, customer_name) values ('8', 'JOE BLOGGS');
Insert into customers(customer_id, customer_name) values ('9', 'JANE POE');
Insert into customers(customer_id, customer_name) values ('10', 'MARK MOE');
Query OK, 1 row affected (0.01 sec)
Query OK, 1 row affected (0.00 sec)
.
Теперь нужно запустить профайлер MySQL, аналитический сервис для мониторинга производительности запросов MySQL. Чтобы включить профиль для текущего сеанса, выполните следующую команду, установив значение 1 (что значит «включено»):
SET profiling = 1;
Query OK, 0 rows affected, 1 warning (0.00 sec)
Затем запустите следующий запрос, чтобы извлечь список клиентов:
Select * from customers;
Вы получите следующий вывод:
+-------------+---------------+
| customer_id | customer_name |
+-------------+---------------+
| 1 | JANE DOE |
| 2 | JANIE DOE |
| 3 | JOHN ROE |
| 4 | MARY ROE |
| 5 | RICHARD ROE |
| 6 | JOHNNY DOE |
| 7 | JOHN SMITH |
| 8 | JOE BLOGGS |
| 9 | JANE POE |
| 10 | MARK MOE |
+-------------+---------------+
10 rows in set (0.00 sec)
Затем запустите команду SHOW PROFILES, чтобы получить информацию о производительности для только что выполненного запроса SELECT:
Вы получите примерно такой вывод:
Выходные данные показывают общее время, потраченное MySQL на извлечение записей из БД. Позже мы сравним эти данные с результатом, полученным при извлечении записей с включенным кэшем запросов. Для этого запишите текущее значение Duration. Предупреждение в выводе можно проигнорировать: оно просто сообщает, что команда SHOW PROFILES будет удалена в следующем релизе MySQL и заменена схемой производительности (Performance Schema).
Выйдите из интерфейса командной строки MySQL.
Только что вы запустили запрос в MySQL без поддержки кэша запросов и записали время, затраченное на извлечение записей. Теперь давайте включим кэш запросов и посмотрим, как изменится производительность при обработке того же запроса.
Требования
Для работы вам понадобится сервер Ubuntu 16.04, настроенный по этому мануалу.
1: Проверка кэша запросов
Перед настройкой кэша запросов нужно проверить, поддерживает ли ваша версия MySQL эту функцию. Сначала подключитесь по ssh к серверу Ubuntu 18.04:
Затем выполните следующую команду, чтобы войти на сервер MySQL как пользователь root:
sudo mysql -u root -p
При появлении запроса введите root пароль сервера MySQL, а затем нажмите Enter, чтобы продолжить.
Используйте следующую команду, чтобы проверить, поддерживается ли кэш запросов:
show variables like 'have_query_cache';
Вы должны получить такой вывод:
Если в have_query_cache установлено значение YES, это означает, что кэш запросов поддерживается вашей версией СУБД. Если ваша версия не поддерживает кэш, можно использовать альтернативные сторонние инструменты для оптимизации производительности MySQL (такие как ProxySQL).
Убедившись, что версия MySQL поддерживает кэш запросов, мы можем приступать к изучению переменных, которые управляют этой функцией.
2: Проверка стандартных переменных кэша запросов
В MySQL кэшем запросов управляет ряд переменных. Сейчас нам нужно проверить значения этих переменных, которые поставляются с MySQL по умолчанию, и разобраться, что контролирует каждая из них.
Чтобы проверить эти переменные, используйте следующую команду:
show variables like 'query_cache_%' ;
В выводе вы увидите переменные:
+------------------------------+----------+
| Variable_name | Value |
+------------------------------+----------+
| query_cache_limit | 1048576 |
| query_cache_min_res_unit | 4096 |
| query_cache_size | 16777216 |
| query_cache_type | OFF |
| query_cache_wlock_invalidate | OFF |
+------------------------------+----------+
5 rows in set (0.00 sec)
Значение query_cache_limit определяет максимальный размер отдельных результатов запроса, которые могут быть кэшированы. Значение по умолчанию составляет 1 048 576 байт, что эквивалентно 1 МБ.
MySQL не обрабатывает кэшированные данные целиком; он обрабатывает их блоками. Минимальный объем памяти, выделяемый каждому блоку, определяется переменной query_cache_min_res_unit. Значение по умолчанию составляет 4096 байт, или 4 КБ.
Переменная query_cache_size контролирует общий объем памяти, выделенной для кэша запросов. Если в ней установлено значение 0, это означает, что кэш запросов отключен. В большинстве случаев по умолчанию может быть установлено значение 16 777 216 (около 16 МБ). Кроме того, следует иметь в виду, что query_cache_size требует как минимум 40 КБ для размещения своих структур. Выделенное здесь значение выравнивается по ближайшему 1024-байтовому блоку – то есть фактическое значение может немного отличаться от установленного вами.
MySQL определяет запросы к кэшу, изучая переменную query_cache_type. Значение 0 или OFF отключает кэширование или извлечение кэшированных запросов. Вы также можете установить значение 1, чтобы включить кэширование для всех запросов, кроме тех, которые начинаются с SELECT SQL_NO_CACHE. Значение 2 позволяет кэшировать только те запросы, которые начинаются с SELECT SQL_CACHE.
Переменная query_cache_wlock_invalidate решает, должен ли MySQL извлекать результаты из кэша, если используемая в запросе таблица заблокирована. Ее значением по умолчанию является OFF.
Примечание: Переменная query_cache_wlock_invalidate устарела с версии MySQL 5.7.20. Вполне возможно, что вы не увидите ее в своем выводе (в зависимости от версии MySQL, которую вы используете).
Изучив системные переменные, которые управляют кэшем запросов MySQL, мы можем проверить, как работает MySQL без кэша.
1: Установка и настройка сервера MySQL
Сначала мы установим сервер MySQL и настроим его для поддержки ProxySQL в качестве бэкенда для обслуживания клиентских запросов.
В Ubuntu 16.04 пакет mysql-server можно установить с помощью этой команды:
sudo apt-get install mysql-server
Нажмите Y, чтобы подтвердить установку.
Затем вам будет предложено выбрать пароль для root-пользователя MySQL. Введите сложный пароль.
Сначала войдите в оболочку MySQL:
Флаг -uroot авторизует вас как пользователя root MySQL, а -p запрашивает пароль пользователя root. Введите тот пароль, который вы выбрали при установке пакета mysql-server, и нажмите Enter.
Теперь нужно создать двух пользователей: одного для ProxySQL (по имени monitor), а второго – для выполнения клиентских запросов и предоставления им необходимых привилегий (здесь мы условно назовем его 8host, но вы можете выбрать другое имя).
Создайте пользователя monitor:
CREATE USER 'monitor'@'%' IDENTIFIED BY 'monitor_password';
Запрос CREATE USER используется для создания нового пользователя, который может подключаться с определенных IP-адресов. Символ % означает, что пользователь может подключиться с любого IP-адреса. IDENTIFIED BY устанавливает пароль нового пользователя; выберите сложный пароль и обязательно запомните его для дальнейшей работы.
После создания пользователя monitor создайте пользователя 8host:
CREATE USER '8host'@'%' IDENTIFIED BY '8host_password';
Затем предоставьте своим новым пользователям требуемые привилегии. Выполните следующую команду для настройки monitor:
GRANT SELECT ON sys.* TO 'monitor'@'%';
Запрос GRANT используется для предоставления привилегий пользователям. Здесь вы предоставили пользователю только право запускать SELECT для всех таблиц в базе данных sys; этого достаточно для прослушивания внутреннего сервера.
Теперь предоставьте пользователю 8host все привилегии на все БД:
GRANT ALL PRIVILEGES on *.* TO '8host'@'%';
Это позволит 8host позже сделать все необходимые запросы для проверки вашей базы данных.
Закройте оболочку mysql:
Вы установили mysql-сервер и создали пользователей для ProxySQL и для выполнения клиентских запросов. Давайте установим ProxySQL.
Требования
Для работы вам понадобится сервер Ubuntu 16.04, настроенный по этому мануалу.
11 Answers 11
Try using the SQL_NO_CACHE (MySQL 5.7) option in your query. (MySQL 5.6 users click HERE )
This will stop MySQL caching the results, however be aware that other OS and disk caches may also impact performance. These are harder to get around.
Before trying to improve performance, try restarting your mysql server. It may be that some process is affecting everything. It happened with me. Although it is a comment that has no direct connection with the issue, it can help many people.
Another alternative that only affects the current connection:
My bad. It was query_cache_size I was looking at, not query_cache_type . I was mixing up yours and SeniorDev's answer.
Any reference to current date/time will disable the query cache for that selection:
There is also configuration option: query_cache_size=0
To disable the query cache at server startup, set the query_cache_size system variable to 0. By disabling the query cache code, there is no noticeable overhead. If you build MySQL from source, query cache capabilities can be excluded from the server entirely by invoking configure with the --without-query-cache option.
You can also run the follow command to reset the query cache.
One problem with the
method is that it seems to only prevent the result of your query from being cached. However, if you're querying a database that is actively being used with the query you want to test, then other clients may cache your query, affecting your results. I am continuing to research ways around this, will edit this post if I figure one out.
But if your cache is filled up by others, you will get the illusion of being fast. But sometimes not.
I'd Use the following:
Using a user-defined variable within a query makes the query resuts uncacheable. I found it a much better indicator than using SQL_NO_CACHE . But you should put the variable in a place where the variable setting would not seriously affect the performance:
"I found it a much better indicator than using SQL_NO_CACHE ." How so? Seems you would need a pretty strong case for using an obscure hack over an explicit keyword, unless the explicit keyword isn't doing what it claims.
@Air I found this solution to work better than SQL_NO_CACHE as well. SQL_NO_CACHE worked for the first time running the query, but then after that it did not work again. I'm assuming this is due to other mechanisms of caching. I think this works better because a search that relies on a variable can't be cached by any layer or mechanism--at least, that's my best guess.
Upvoted. For me, SQL_NO_CACHE or /*!40001 SQL_NO_CACHE */ made no difference at all compared to regular query. However I could see an increase of query duration time of 50% by using , (SELECT @a:=NULL) . Anyways, This does not avoid the OS/Disk cache. See Ian's answer. Still, a worthy improvement. Thanks!
If you want to disable the Query cache set the 'query_cache_size' to 0 in your mysql configuration file . If its set 0 mysql wont use the query cache.
Whilst some of the answers are good, there is a major caveat.
The mysql queries may be prevented from being cached, but it won't prevent your underlying O.S caching disk accesses into memory. This can be a major slowdown for some queries especially if they need to pull data from spinning disks.
So whilst it's good to use the methods above, I would also try and test with a different set of data/range each time, that's likely not been pulled from disk into disk/memory cache.
You must change SQL string. Because SQL string is a cache key. For example, add a timestamp to a SQL comment.
Function for PHP:
Linked
Related
Hot Network Questions
To subscribe to this RSS feed, copy and paste this URL into your RSS reader.
Site design / logo © 2022 Stack Exchange Inc; user contributions licensed under cc by-sa. rev 2022.5.10.42086
Кэш запросов – это функция MySQL, которая позволяет ускорить извлечение данных из БД. Это делается путем сохранения в памяти операторов SELECT с извлеченными записями; если позже клиент отправляет идентичный запрос, данные выводятся быстрее, поскольку не нужно повторно выполнять команды в БД.
По сравнению с данными, хранящимися на диске, кэшированные данные из RAM (Random Access Memory) можно получить быстрее, что улучшает операции ввода/вывода (I/O). Например, благодаря кэшу запросов производительность сайтов WordPress или e-commerce порталов с большим количеством операций чтения и почти не меняющимися данными может значительно вырасти.
В этом мануале вы научитесь настраивать кэш запросов MySQL. Сначала мы попробуем работать без кэша, чтобы оценить стандартное время обработки запроса. После настройки кэша запросов мы протестируем сервер MySQL и посмотрим на разницу в производительности.
Примечание: Кэш запросов устарел в версии MySQL 5.7.20 и был удален в MySQL 8.0, но он по-прежнему является мощным инструментом и его можно использовать в тех версиях MySQL, которые поддерживают его. В более новых версиях MySQL можно использовать альтернативные сторонние инструменты для оптимизации производительности базы данных MySQL (такие как ProxySQL).
Встроенный механизм кэширования запросов в MySQL.
MySQL содержит встроенный механизм кэширования запросов, который, однако не включен по умолчанию. Вот такие параметры выставленны по умолчанию в MySQL 5.0:
mysql> show variables like 'query_cache%';
+------------------------------+---------+
| Variable_name | Value |
+------------------------------+---------+
| query_cache_limit | 1048576 |
| query_cache_min_res_unit | 4096 |
| query_cache_size | 0 |
| query_cache_type | ON |
| query_cache_wlock_invalidate | OFF |
+------------------------------+---------+
Чтобы включить кэш запросов и выделить под него 32 мегабайта памяти можно выполнить запрос set @@global.query_cache_size= 32 * 1024 * 1024 ; с правами суперпользователя, а чтобы сделать эту настройку постоянной, следует добавить в my.cnf в подраздел [mysqld] строчку query_cache_size=32M. Второй полезный параметр - query_cache_limit задает максимальный объем результата выполнения запроса, который может быть помещен в кэш
После включения кэш работает автоматически:
- При каждом запросе типа SELECT вычисляет хэш-сумму строки запроса и ищет ее в кэше. Если находит - возвращает рузельтат из кэша, если нет - выполняет запрос, а результат заносит в кэш (если результат не больше значения query_cache_limit).
- При каждом запросе типа UPDATE, REPLACE, INSERT, DELETE, TRUNCATE или ALTER, удаляет из кэша все запросы, использующие таблицу, подвергшуюся обновлению.
Отметим следующие особенности работы кэша:
- Различие запросов определяется буквально, сравнение чувствительно к реестру. Поэтому SELECT * FROM news и select * FROM news будут для кэша двумя разными запросами.
- В кэш всегда попадает результат выполнения запроса целиком, результаты выполнения подзапросов не кэшируются.
- Кэш работает одинаково для запросов к таблицам с различными механизмами хранения. MySQL также кэширует запросы SELECT к представлениям (VIEW).
- Ряд запросов не подлежит кэшированию:
- Запросы, содержащие одну из недетерминированных функций: NOW(), SLEEP(), RAND(), CURTIME(), LAST_INSERT_ID() и.др.
- Запросы, использующие функции или хранимые процедуры, определенные пользователем.
- Запросы, использующие значения пользовательских или локальных переменных.
- Запросы, обращающиеся к базам данных mysql, INFORMATION_SCHEMA или performance_schema.
- Запросы, обращающиеся к таблицам, разбитым на партиции (начиная с MySQL версий 5.1.63, 5.5.23, 5.6.5).
- Запросы типа SELECT . FOR UPDATE, SELECT . IN SHARE MODE, SELECT . INTO OUTFILE, SELECT . INTO DUMPFILE, SELECT * FROM . WHERE autoincrement_col IS NULL.
- Запросы, использующие временные таблицы.
- Запросы, не обращающиеся к таблицам.
- Запросы, которые генерируют предупреждения (warnings).
- В случае, если пользователь имеет права не на всю таблицу, а только на определенные колонки таблицы. Это исключение — следствие того, что кэш запросов один для всех пользователей, а права доступа средствами кэша проверяются лишь на уровне таблиц.
SELECT t.*, ( SELECT body FROM entities WHERE >) body
FROM
( SELECT e2.type,e2.id,e2.title,e2.active,
count ( * ) - IF ( e2.type= 3 , 1 , 0 ) cnt, MAX ( e.id ) lastid, MAX ( e.created ) lastcreated
FROM entities e
LEFT JOIN entities e2
ON e2.id= IF ( e.foreparent,e.foreparent,e.id )
WHERE e.active = 1 AND e2.active = 1 AND e.type= 3
GROUP BY e2.id
ORDER BY MAX ( e.created ) DESC LIMIT 10 ) t
ORDER BY lastcreated DESCЗапрос выполняет сортировку статей и тем по дате последнего комментария. Обращения к главной странице сайта происходят чаще, чем добавление комментариев или статей, поэтому кэш достаточно эффективен.
Замечание: если системная переменная query_cache_wlock_invalidate принимает значение OFF, то блокировка таблицы для записи не сбрасывает кэшированные запросы с участием данной таблицы. В этом случае через query cache будет возможно получение данных из заблокированной таблицы.
Текущее состояние кэша
Посмотреть состояние кэша можно с помощью запроса:
mysql> SHOW GLOBAL STATUS LIKE 'Qcache%';
+-------------------------+----------+
| Variable_name | Value |
+-------------------------+----------+
| Qcache_free_blocks | 973 |
| Qcache_free_memory | 14282000 |
| Qcache_hits | 3293750 |
| Qcache_inserts | 252819 |
| Qcache_lowmem_prunes | 0 |
| Qcache_not_cached | 66645 |
| Qcache_queries_in_cache | 1342 |
| Qcache_total_blocks | 3709 |
+-------------------------+----------+
8 rows in set (0.00 sec)- Qcache_free_memory - объем свободной памяти, отведенной под кэш.
- Qcache_hits - количество запросов, отработанных из кэша.
- Qcache_inserts - количество вставок запросов в кэш.
- Qcache_lowmem_prunes - количество высвобождений памяти из-за наполненности кэша.
- Qcache_not_cached - количество запросов, не подлежащих кэшированию.
- Qcache_queries_in_cache - количество запросов, находящихся в кэше в настоящее время.
Мерой эффективности кэша может служить отношение Qcache_hits / (Qcache_inserts + Qcache_not_cached).
Заключение
Вы научились настраивать прозрачное кэширование с помощью ProxySQL. Также мы провели два теста – с кэшированием и без – и убедились, что ProxySQL очень хорошо влияет на обработку запросов.
Оптимизация для подобных таблиц — вынести часто изменяющиеся данные в отдельную таблицу. Например, есть таблица статей, в которой также хранятся и количество комментариев к ней. Посколько количество комментариев изменяется часто, а сама статья практически не меняется имеет смысл вынести количество комментариев в отдельную таблицу, позволяя при этом избегать частой инвалидации кеша статей.
Использование кеша запросов полностью прозрачно для клиента. Клиент не знает о том, выполнил ли 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 удаляет результаты выборок из кеша при любом изменении таблицы внутри транзакции (хотя мог бы не удалять до тех пор, пока транзакция не зафиксирована). Кроме этого, все выборки из этой таблицы не будут кешироваться до тех пор, пока транзакция не зафиксирована.
- Qcache_free_blocks показывает сколько свободных блоков есть в кеше;
- Qcache_total_blocks — количество занятых блоков;
- Qcache_free_memory говорит о том, сколько свободной памяти осталось в кеше;
- Qcache_hits — количество запросов, результаты которых были взяты из кеша;
- Qcache_inserts — количество запросов, которые были добавлены в кеш;
- Qcache_lowmem_prunes — количество запросов, которые были удалены из кеша из-за нехватки памяти;
- Qcache_not_cached — количество запросов, которые не были записаны в кеш из-за использования функций работы со временем и т.п.;
- Qcache_queries_in_cache — количество запросов, которые находятся в кеше.
- query_cache_type = (ON, DEMAND, OFF) — определяет включено ли кеширование или нет(ON, OFF). При использовании DEMAND кешироваться будут только запросы, в которых есть директива SQL_CACHE;
- query_cache_size — размер кеша запросов. query_cache_size = 0 отключает использование кеша;
- query_cache_limit — размер максимальной выборки, хранимой в кеше;
- query_cache_min_res_unit — минимальный размер блока, хранимого в кеше;
- query_cache_wlock_invalidate — определяет будут ли данные браться из кеша, если таблица, к которым они относятся заблокирована на чтение.
В момент начала записи 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.
P.S. пишите в личку темы статей по MySQL, которые вы хотели бы прочитать.
Кэширование запросов позволяет повысить производительность приложений, не погружаясь в структуру самих запросов. Мы рассмотрим встроенный в MySQL механизм кэширования запросов и альтернативный подход для случаев, когда встроенный механизм неприменим.
Как избежать использования кэша?
В ряде случаев, желательно не использовать кэш. Наиболее распространены две ситуации:
- Вы делаете запросы, которые точно не повторятся и не хотите нагружать кэш.
- Вы занимаетесь оптимизацией запроса и хотите измерять время его выполнения.
Для выполнения запроса без использования кэша применяется директива SQL_NO_CACHE, которую помещают сразу после оператора SELECT. Например:
Замечание. Если сервер исполняет большое количество быстрых запросов, кэш может оказывать негативное влияние на производительность. Так как кэш обрабытывает запросы только последовательно, связанная с ним часть исполнения запроса будет использовать только одно ядро процессора. Если кэш приводит к снижению производительности, его нужно отключить в конфигурационном файле.
5: Тестирование MySQL с поддержкой кэша запросов
Теперь давайте повторим тот запрос, который мы выполнили в разделе 3, чтобы посмотреть, как кэш запросов оптимизировал производительность сервера MySQL.
Сначала подключитесь к серверу MySQL как root:
sudo mysql -u root -p
Введите свой root пароль для сервера базы данных и нажмите Enter, чтобы продолжить.
Теперь проверьте свой набор переменных, чтобы убедиться, что вы включили кэш запросов:
show variables like 'query_cache_%' ;
Вы увидите следующий вывод:
+------------------------------+----------+
| Variable_name | Value |
+------------------------------+----------+
| query_cache_limit | 262144 |
| query_cache_min_res_unit | 4096 |
| query_cache_size | 10485760 |
| query_cache_type | ON |
| query_cache_wlock_invalidate | OFF |
+------------------------------+----------+
5 rows in set (0.01 sec)Переменная query_cache_type имеет значение ON; это подтверждает, что вы включили кэш запросов с параметрами, которые определили на предыдущем этапе.
Перейдите в базу данных sample_db, которую вы создали ранее.
SET profiling = 1;
Затем выполните запрос, чтобы вывести список всех клиентов как минимум два раза (чтоб собрать достаточно информации для профилирования).
После того как вы выполните первый запрос, MySQL создаст кэш результатов, и, следовательно, вы должны повторить запрос еще раз, чтобы вызвать значение из кэша, если все работает правильно:
Select * from customers;
Select * from customers;Затем запросите информацию о профилях:
Вы получите такой вывод:
Как видите, время, затраченное на выполнение запроса, резко сократилось с 0,00044075 (без кэша запросов ) до 0,00026000 (обратите внимание на второй запрос).
Вы можете оценить преимущества кэширования запросов с помощью детального профилирования первого запроса:
SHOW PROFILE FOR QUERY 1;
+--------------------------------+----------+
| Status | Duration |
+--------------------------------+----------+
| starting | 0.000025 |
| Waiting for query cache lock | 0.000004 |
| starting | 0.000003 |
| checking query cache for query | 0.000045 |
| checking permissions | 0.000008 |
| Opening tables | 0.000014 |
| init | 0.000018 |
| System lock | 0.000008 |
| Waiting for query cache lock | 0.000002 |
| System lock | 0.000018 |
| optimizing | 0.000003 |
| statistics | 0.000013 |
| preparing | 0.000010 |
| executing | 0.000003 |
| Sending data | 0.000048 |
| end | 0.000004 |
| query end | 0.000006 |
| closing tables | 0.000006 |
| freeing items | 0.000006 |
| Waiting for query cache lock | 0.000003 |
| freeing items | 0.000213 |
| Waiting for query cache lock | 0.000019 |
| freeing items | 0.000002 |
| storing result in query cache | 0.000003 |
| cleaning up | 0.000012 |
+--------------------------------+----------+
25 rows in set, 1 warning (0.00 sec)Выполните следующую команду, чтобы отобразить информацию о втором запросе:
SHOW PROFILE FOR QUERY 2;
+--------------------------------+----------+
| Status | Duration |
+--------------------------------+----------+
| starting | 0.000024 |
| Waiting for query cache lock | 0.000003 |
| starting | 0.000002 |
| checking query cache for query | 0.000006 |
| checking privileges on cached | 0.000003 |
| checking permissions | 0.000027 |
| sending cached result to clien | 0.000187 |
| cleaning up | 0.000008 |
+--------------------------------+----------+
8 rows in set, 1 warning (0.00 sec)Выводы профайлера показывают, что MySQL потратил меньше времени на обработку второго запроса, потому что он мог извлечь данные из кэша запросов, а не с диска. Вы можете сравнить два вывода для каждого из запросов. Если вы посмотрите информацию о профиле для QUERY 2, состояние sending cached result to client показывает, что данные были прочитаны из кэша и таблицы не открывались (статуса Opening tables не будет).
Если на вашем сервере включена функция кэширования запросов MySQL, вы сможете улучшить скорость чтения данных.
3: Тестирование сервера без кэширования с помощью mysqlslap
На данном этапе нужно загрузить тестовую базу данных, чтобы вы могли выполнять запросы к ней с помощью mysqlslap и измерить задержку без кэширования, установив контрольный показатель для скорости ваших запросов. Вы также узнаете, как ProxySQL хранит записи запросов в таблице stats_mysql_query_digest.
mysqlslap – это клиентский эмулятор нагрузки, который используется для нагрузочного тестирования MySQL. Он может проверить работу сервера MySQL с помощью автоматически сгенерированных запросов или нескольких пользовательских запросов, выполняемых в базе данных. Он устанавливается вместе с клиентским пакетом MySQL, поэтому вам не нужно его устанавливать отдельно.
Давайте загрузим БД с тестовыми данными. В этом мануале мы предлагаем использовать этот пример. База данных employees содержит большой набор данных, который может наглядно показать различия в оптимизации запросов. Эта БД содержит шесть таблиц и более 300 000 записей о сотрудниках. Это поможет вам эмулировать крупномасштабную производственную нагрузку.
Чтобы загрузить эту базу данных, сначала клонируйте репозиторий Github с помощью этой команды:
Затем войдите в каталог test_db и загрузите базу данных на сервер MySQL:
cd test_db
mysql -uroot -p < employees.sqlЭта команда использует перенаправление оболочки для чтения запросов SQL в файле employee.sql и выполнения их на сервере MySQL, чтобы создать структуру базы данных.
Вы увидите такой вывод:
INFO
CREATING DATABASE STRUCTURE
INFO
storage engine: InnoDB
INFO
LOADING departments
INFO
LOADING employees
INFO
LOADING dept_emp
INFO
LOADING dept_manager
INFO
LOADING titles
INFO
LOADING salaries
data_load_time_diff
00:00:32Как только база данных будет загружена на ваш сервер MySQL, убедитесь, что mysqlslap работает:
mysqlslap -u8host -p -P6033 -h127.0.0.1 --auto-generate-sql --verbose
mysqlslap предоставляет флаги, аналогичные флагам клиента mysql; Вот такие флаги используются в этой команде:
- -u задает пользователя для подключения к серверу.
- -p запрашивает пароль пользователя.
- -P подключается через указанный порт.
- -h подключается к указанному хосту.
- –auto-generate-sql позволяет MySQL выполнять нагрузочное тестирование, используя собственные сгенерированные запросы.
- –verbose выводит полученную информацию в расширенном формате.
Вы получите подобный вывод:
Benchmark
Average number of seconds to run all queries: 0.015 seconds
Minimum number of seconds to run all queries: 0.015 seconds
Maximum number of seconds to run all queries: 0.015 seconds
Number of clients running queries: 1
Average number of queries per client: 0В этом выводе вы можете увидеть среднее, минимальное и максимальное количество секунд, потраченных на выполнение всех запросов. Это дает нам представление о количестве времени, необходимом для выполнения запросов несколькими клиентами. В этом выводе для выполнения запросов был использован только один клиент.
Затем выясните, какие запросы выполнял mysqlslap в последней команде, посмотрев stats_mysql_query_digest в ProxySQL. Это даст дайджест запросов, который является нормализованной формой оператора SQL и на который можно ссылаться позже для включения кэширования.
Войдите в интерфейс администратора ProxySQL с помощью этой команды:
mysql -uadmin -p -h 127.0.0.1 -P6032
Затем выполните этот запрос, чтобы найти информацию в таблице stats_mysql_query_digest:
SELECT count_star,sum_time,hostgroup,digest,digest_text FROM stats_mysql_query_digest ORDER BY sum_time DESC;
Вы увидите следующий вывод:
Предыдущий запрос извлекает данные из таблицы stats_mysql_query_digest, которая содержит информацию обо всех выполненных запросах в ProxySQL. Здесь у вас есть пять столбцов:
- count_star: количество выполнений запроса.
- sum_time: общее время в миллисекундах, которое потребовалось для выполнения этого запроса.
- hostgroup: группа хостов, используемая для выполнения запроса.
- digest: дайджест выполненного запроса.
- digest_text: сам запрос. В нашем примере второй запрос параметризован с помощью символа «?»вместо переменных параметров. select @@version_comment limit 1 и select @@version_comment limit 2 сгруппированы как один и тот же запрос с одним и тем же дайджестом.
Теперь, когда вы знаете, как проверить данные запроса в таблице stats_mysql_query_digest, выйдите из оболочки mysql:
База данных, которую вы скачали, содержит несколько таблиц с тестовыми данными. Теперь давайте протестируем запросы в таблице dept_emp, выбрав все записи, чье значение from_date больше 2000-04-20, и записав среднее время выполнения.
Используйте эту команду для запуска теста:
mysqlslap -u8host -P6033 -p -h127.0.0.1 --concurrency=100 --iterations=20 --create-schema=employees --query="SELECT * from dept_emp WHERE from_date>'2000-04-20'" --verbose
В команде использованы такие флаги:
- –concurrency=100: устанавливает количество симулируемых пользователей, в данном случае 100.
- –iterations=20: запускает тест 20 раз и вычисляет результаты по всем запускам.
- –create-schema=employees: задает базу данных employees.
- –query=”SELECT * from dept_emp WHERE from_date>’2000-04-20′”: вы указывает запрос, выполненный в тесте.
Тест займет несколько минут. После того, как это будет сделано, вы получите результаты, подобные следующим:
Benchmark
Average number of seconds to run all queries: 18.117 seconds
Minimum number of seconds to run all queries: 8.726 seconds
Maximum number of seconds to run all queries: 22.697 seconds
Number of clients running queries: 100
Average number of queries per client: 1Ваши результаты могут немного отличаться. Сохраните где-нибудь эти цифры, чтобы сравнить их с результатами после включения кэширования.
Теперь повторим тот же тест, но уже с кэшированием ProxySQL.
2: Установка и настройка сервера ProxySQL
Теперь вы можете установить сервер ProxySQL, который будет использоваться в качестве уровня кэширования ваших запросов. Уровень кэширования работает как промежуточный уровень между вашими серверами приложений и внутренними серверами баз данных; он используется для подключения к базе данных и сохранения результатов наиболее частых запросов в ее памяти для быстрого доступа к ним.
Далее установите этот пакет с помощью dpkg:
sudo dpkg -i proxysql_2.0.4-ubuntu16_amd64.deb
После установки запустите ProxySQL с помощью этой команды:
sudo systemctl start proxysql
Вы можете проверить, правильно ли запущен ProxySQL, с помощью этой команды:
sudo systemctl status proxysql
Вы получите примерно такой результат:
Теперь пришло время подключить ваш сервер ProxySQL к серверу MySQL. Для этого используйте SQL-интерфейс администратора ProxySQL, который по умолчанию прослушивает порт 6032 на локальном хосте (имя пользователя – admin, пароль – admin).
Подключитесь к интерфейсу, выполнив команду:
mysql -uadmin -p -h 127.0.0.1 -P6032
Введите учетные данные.
Флаг -uadmin задает имя пользователя admin, а флаг -h указывает localhost в качестве хоста. Порт 6032 определяется флагом -P.
Мы явно указали хост и порт, потому что по умолчанию клиент MySQL подключается с помощью локального файла сокетов и порта 3306.
Теперь, когда вы вошли в оболочку mysql как администратор, настройте пользователя monitor, чтобы ProxySQL мог его использовать. Сначала используйте стандартные запросы SQL, чтобы установить значения двух глобальных переменных:
UPDATE global_variables SET variable_value='monitor' WHERE variable_name='mysql-monitor_username';
UPDATE global_variables SET variable_value='monitor_password' WHERE variable_name='mysql-monitor_password';Переменная mysql-monitor_username указывает имя пользователя MySQL, которое будет использоваться для проверки состояния сервера бэкенда. Переменная mysql-monitor_password указывает пароль для подключения к этому серверу. Укажите здесь пароль, который вы создали для пользователя monitor.
Каждый раз, когда вы вносите изменение через интерфейс администратора ProxySQL, вам нужно использовать правильную команду LOAD, чтобы применить изменения к работающему экземпляру ProxySQL. Поскольку мы изменили глобальные переменные MySQL, давайте загрузим их в RUNTIME, чтобы применить изменения:
LOAD MYSQL VARIABLES TO RUNTIME;
Затем сохраните изменения в базе данных на диске, чтобы сделать эти настройки постоянными. ProxySQL использует собственную локальную базу данных SQLite для хранения таблиц и переменных:
SAVE MYSQL VARIABLES TO DISK;
Теперь нужно рассказать ProxySQL о внутреннем сервере. Таблица mysql_servers содержит информацию о каждом бэкенд сервере, к которому ProxySQL может подключаться и выполнять запросы, поэтому добавьте в нее новую запись, используя стандартный оператор SQL INSERT:
INSERT INTO mysql_servers(hostgroup_id, hostname, port) VALUES (1, '127.0.0.1', 3306);
Чтобы изменения вступили в силу, снова запустите LOAD и SAVE:
LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;Наконец, сообщите ProxySQL, какой пользователь будет подключаться к бэкенд серверу; это будет пользователь 8host. Укажите в команде его пароль.
INSERT INTO mysql_users(username, password, default_hostgroup) VALUES ('8host', '8host_password', 1);
Таблица mysql_users содержит информацию о пользователях для подключения к бэкенд серверам. Мы указали параметры username, password и default_hostgroup.
Чтобы изменения вступили в силу, снова запустите LOAD и SAVE:
LOAD MYSQL USERS TO RUNTIME;
SAVE MYSQL USERS TO DISK;Выйдите из оболочки СУБД:
Чтобы убедиться, что вы можете подключиться к бэкенд серверу с помощью ProxySQL, выполните следующий тестовый запрос:
mysql -u8host -h127.0.0.1 -p -P6033 -e "SELECT @@HOSTNAME as hostname"
В этой команде вы использовали флаг -e, чтобы выполнить запрос и закрыть соединение. Запрос выведет имя хоста бэкенд сервера.
Примечание: Для прослушивания входящих соединений ProxySQL по умолчанию использует порт 6033.
Вывод будет выглядеть следующим образом (вместо your_hostname будет имя вашего хоста):
Итак, вы настроили ProxySQL, и теперь он использует MySQL в качестве бэкэнда. Чтобы проверить, как все работает, вы подключились к бэкенду с помощью ProxySQL. Теперь давайте используем mysqlslap для оценки производительности запросов без кэширования.
Заключение
Вы настроили кэш запросов для ускорения работы сервера MySQL в Ubuntu 18.04. Эта функция может повысить скорость работы вашего веб-сайта или приложения. Кэширование устраняет обработку лишних операторов SQL и является очень и популярным методом оптимизации базы данных.
4: Тестирование сервера с включенным кэшированием с помощью mysqlslap
На этом этапе вы увидите, как кэширование помогаем уменьшить задержку при выполнении одинаковых запросов. Здесь мы можем определить выполненные запросы, извлечь их дайджесты из таблицы stats_mysql_query_digest в ProxySQL и использовать их для включения кэширования. Затем мы еще раз запустим тесты, чтобы проверить разницу.
Чтобы включить кэширование, нужно знать дайджесты запросов, которые будут кэшироваться. Войдите в интерфейс администратора ProxySQL с помощью этой команды:
mysql -uadmin -p -h127.0.0.1 -P6032
Затем запустите этот запрос еще раз, чтобы получить список выполненных запросов и их дайджестов:
SELECT count_star,sum_time,hostgroup,digest,digest_text FROM stats_mysql_query_digest ORDER BY sum_time DESC;
Вы получите такой результат:
Посмотрите на первую строку. Речь идет о запросе, который был выполнен 2000 раз. Возьмите его дайджест и сохраните его, чтобы использовать его при добавлении правила кэширования.
Следующие несколько команд добавят в ProxySQL новое правило, которое будет соответствовать дайджесту предыдущего запроса и присвоит ему значение cache_ttl. cache_ttl – это количество миллисекунд, в течение которых результат будет кэшироваться в памяти.
INSERT INTO mysql_query_rules(active, digest, cache_ttl, apply) VALUES(1,'0xC5DDECD7E966A6C4',2000,1);
Эта команда добавит новую запись в таблицу mysql_query_rules, которая содержит все правила, применяемые перед выполнением запроса. В этом примере мы добавили значение для столбца cache_ttl, и в результате соответствующий запрос по данному дайджесту будет кэшироваться в течение количества миллисекунд, указанных в этом столбце. В столбце apply мы указываем 1, чтобы правило применялось к запросам.
Загрузите и сохраните изменения, а затем выйдите из оболочки mysql:
LOAD MYSQL QUERY RULES TO RUNTIME;
SAVE MYSQL QUERY RULES TO DISK;
exit;Теперь, когда кэширование включено, повторите тест еще раз, чтобы сравнить результаты:
mysqlslap -u8host -P6033 -p -h127.0.0.1 --concurrency=100 --iterations=20 --create-schema=employees --query="SELECT * from dept_emp WHERE from_date>'2000-04-20'" --verbose
Вы получите такой вывод:
Benchmark
Average number of seconds to run all queries: 7.020 seconds
Minimum number of seconds to run all queries: 0.274 seconds
Maximum number of seconds to run all queries: 23.014 seconds
Number of clients running queries: 100
Average number of queries per client: 1Как видите, среднее время выполнения запроса сократилось с 18.117 секунд до 7.020.
Читайте также: