# Кэш запросов

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

* [qcache_max_bytes](../Server_settings/Searchd.md#qcache_max_bytes) — ограничение на использование RAM для хранения кэшированных запросов. По умолчанию установлено в 16 МБ. Установка `qcache_max_bytes` в 0 полностью отключает кэш запросов.
* [qcache_thresh_msec](../Server_settings/Searchd.md#qcache_thresh_msec) — минимальное время выполнения запроса в миллисекундах для кеширования. Запросы, которые выполняются быстрее этого времени, *не будут* кешироваться. По умолчанию 3000 мс, или 3 секунды.
* [qcache_ttl_sec](../Server_settings/Searchd.md#qcache_ttl_sec) — время жизни кэшированной записи, или TTL. Запросы будут оставаться в кэше в течение этого времени. По умолчанию 60 секунд, или 1 минута.

Эти настройки можно изменить на лету, используя оператор `SET GLOBAL`:

```sql
mysql> SET GLOBAL qcache_max_bytes=128000000;
```

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

Кэш запросов работает следующим образом. При включении каждый результат полнотекстового поиска полностью сохраняется в памяти. Это происходит после полнотекстового совпадения, фильтрации и ранжирования, так что по сути мы сохраняем пары {docid,weight} для `total_found`. Сжатые совпадения могут занимать в среднем от 2 до 12 байт на совпадение, в основном в зависимости от дельт между последовательными docid. По завершении запроса мы проверяем пороги времени и размера, и либо сохраняем сжатый набор результатов для повторного использования, либо отбрасываем его.

Обратите внимание, что влияние кэша запросов на RAM не ограничивается `qcache_max_bytes`! Например, если у вас выполняется 10 одновременных запросов, каждый из которых находит до 1 млн совпадений (после фильтров), то пиковое временное использование RAM окажется в диапазоне от 40 МБ до 240 МБ, даже если запросы достаточно быстрые и не кэшируются.

Запросы могут использовать кэш, когда совпадают таблица, полнотекстовый запрос (то есть содержимое `MATCH()`), ранжировщик и совместимы фильтры. Это значит:

* Полнотекстовая часть внутри `MATCH()` должна совпадать посимвольно. Добавьте один пробел — и это уже другой запрос, с точки зрения кэша запросов.
* Ранжировщик (и его параметры, если есть, для пользовательских ранжировщиков) должен совпадать посимвольно.
* Фильтры должны быть надмножеством оригинальных фильтров. Вы можете добавить дополнительные фильтры и все равно попасть в кэш. (В этом случае дополнительные фильтры будут применены к кэшированному результату.) Но если вы уберёте какой-то фильтр, это уже будет новый запрос.

Записи кэша истекают по TTL и также инвалидируются при ротации таблиц, или при выполнении `TRUNCATE`, или `ATTACH`. Обратите внимание, что в настоящее время записи не инвалидируются при произвольных записях в RT-таблицу! Поэтому кэшированный запрос может возвращать старые результаты в течение времени жизни TTL.

Вы можете проверить текущий статус кэша с помощью [SHOW STATUS](../Node_info_and_management/Node_status.md#SHOW-STATUS) через переменные `qcache_XXX`:

```sql
mysql> SHOW STATUS LIKE 'qcache%';
+-----------------------+----------+
| Counter               | Value    |
+-----------------------+----------+
| qcache_max_bytes      | 16777216 |
| qcache_thresh_msec    | 3000     |
| qcache_ttl_sec        | 60       |
| qcache_cached_queries | 0        |
| qcache_used_bytes     | 0        |
| qcache_hits           | 0        |
+-----------------------+----------+
6 rows in set (0.00 sec)
```
<!-- proofread -->

