La caché de consultas almacena los resultados de las consultas SELECT para que, si se recibe una consulta idéntica en el futuro, los resultados se puedan devolver rápidamente.

Esto es extremadamente útil en entornos de alta lectura y baja escritura (como la mayoría de los sitios web). No se escala bien en entornos con alto rendimiento en máquinas de varios núcleos, por lo que está deshabilitado de forma predeterminada.

Tenga en cuenta que la caché de consultas no se puede habilitar en determinados entornos. Ver limitaciones.

Configuración de la caché de consultas

A menos que MariaDB se haya creado específicamente sin la caché de consultas, la caché de consultas siempre estará disponible, aunque inactiva. los have_query_cache La variable del servidor mostrará si la caché de consultas está disponible.

SHOW VARIABLES LIKE'have_query_cache';+------------------+-------+| Variable_name    |Value|+------------------+-------+| have_query_cache | YES   |+------------------+-------+

Si esto se establece en NO, no puede habilitar la caché de consultas a menos que reconstruya o reinstale una versión de MariaDB con la caché disponible.

Para ver si la caché está habilitada, vea la variable de servidor query_cache_type. Está habilitado de forma predeterminada en las versiones de MariaDB hasta 10.1.6, pero deshabilitado a partir de MariaDB 10.1.7 – si es necesario, habilítelo configurando query_cache_type para 1.

Aunque habilitado en versiones anteriores a MariaDB 10.1.7, query_cache_size está por defecto en 0 KB allí, lo que efectivamente deshabilita la caché de consultas. Desde 10.1.7 en adelante, el tamaño de la caché es de 1 MB de forma predeterminada. Si es necesario, configure el caché en un tamaño lo suficientemente grande, por ejemplo:

SETGLOBAL query_cache_size =1000000;

Empezando desde MariaDB 10.1.7, query_cache_type se establece automáticamente en ON si el servidor se inicia con el query_cache_size establecido en un valor distinto de cero (y no predeterminado).

Consulte Limitar el tamaño de la caché de consultas a continuación para obtener más detalles.

Cómo funciona la caché de consultas

Cuando la caché de consultas está habilitada y se procesa una nueva consulta SELECT, la caché de consultas se examina para ver si la consulta aparece en la caché.

Las consultas se consideran idénticas si utilizan la misma base de datos, la misma versión de protocolo y el mismo juego de caracteres predeterminado. Las declaraciones preparadas siempre se consideran diferentes a las declaraciones no preparadas; consulte Estructura interna de la caché de consultas para obtener más información.

Si la consulta idéntica no se encuentra en la caché, la consulta se procesará normalmente y luego se almacenará, junto con su conjunto de resultados, en la caché de consultas. Si la consulta se encuentra en la caché, los resultados se extraerán de la caché, que es mucho más rápido que procesarla normalmente.

Las consultas se examinan distinguiendo entre mayúsculas y minúsculas, por lo que:

SELECT*FROM t

Es diferente de :

select*from t

Los comentarios también se consideran y pueden hacer que las consultas sean diferentes, por lo que:

/* retry */SELECT*FROM t

Es diferente de :

/* retry2 */SELECT*FROM t

Ver el query_cache_strip_comments variable de servidor para una opción para eliminar los comentarios antes de realizar la búsqueda.

Cada vez que se realizan cambios en los datos de una tabla, se borran todos los resultados afectados en la caché de consultas. No es posible recuperar datos obsoletos de la caché de consultas.

Cuando se agota el espacio asignado a la caché de consultas, los resultados más antiguos se eliminarán de la caché.

Cuando usas query_cache_type=ONy la consulta especifica SQL_NO_CACHE (no distingue entre mayúsculas y minúsculas), el servidor no almacenará en caché la consulta y no obtendrá resultados de la caché de consultas.

Cuando usas query_cache_type=DEMAND (después MDEV-6631 solicitud de función) y la consulta especifica SQL_CACHE, el servidor almacenará en caché la consulta.

Un punto importante de MDEV-6631 es: cambiar entre query_cache_type=ON y query_cache_type=DEMAND puede “desactivar” la caché de consultas de consultas antiguas sin la SQL_CACHE cadena, que aún no está definida si deberíamos incluir otra query_cache_type (DEMAND_NO_PRUNE) o no permitir el uso de consultas antiguas

Consultas almacenadas en la caché de consultas

Si el query_cache_type la variable del sistema está establecida en 1, o ON, todas las consultas que se ajusten a las restricciones de tamaño se almacenarán en la caché a menos que contengan un SQL_NO_CACHE cláusula, o son de una naturaleza que el almacenamiento en caché no tiene sentido, por ejemplo, haciendo uso de una función que devuelve la hora actual. Mira esto SQL_NO_CACHE forzará al servidor a no usar bloqueos de caché de consultas.

Si alguna de las siguientes funciones está presente en una consulta, no se almacenará en caché. Las consultas con estas funciones a veces se denominan “no deterministas”; no se confunda con el uso de este término en otros contextos.

PUNTO DE REFERENCIA() CONNECTION_ID ()
CONVERT_TZ () CURDATE ()
FECHA ACTUAL() TIEMPO ACTUAL()
FECHA Y HORA ACTUAL() CURTIME ()
BASE DE DATOS() ENCRYPT () (un parámetro)
FOUND_ROWS () GET_LOCK ()
LAST_INSERT_ID () CARGAR ARCHIVO()
MASTER_POS_WAIT () AHORA()
ALEATORIO () RELEASE_LOCK ()
DORMIR() SYSDATE ()
UNIX_TIMESTAMP () (sin parámetros) USUARIO()
UUID () UUID_SHORT ()

Tampoco se agregará una consulta a la caché si:

  • Tiene la forma:
    • SELECCIONAR SQL_NO_CACHE …
    • SELECCIONAR … EN SALIDA …
    • SELECCIONAR … EN DUMPFILE …
    • SELECCIONAR … PARA ACTUALIZAR
    • SELECCIONAR * DESDE … DONDE autoincrement_column ES NULO
    • SELECCIONAR … BLOQUEAR EN MODO COMPARTIR
  • Utiliza tabla TEMPORAL
  • No usa tablas en absoluto
  • Genera una advertencia
  • El usuario tiene un privilegio a nivel de columna en cualquier tabla de la consulta.
  • Accede a una tabla desde INFORMATION_SCHEMA, mysql o la base de datos performance_schema
  • Hace uso de variables de usuario o locales.
  • Hace uso de funciones almacenadas
  • Hace uso de funciones definidas por el usuario
  • Está dentro de una transacción con el nivel de aislamiento SERIALIZABLE
  • Está consultando una tabla dentro de una transacción después de que la misma tabla ejecutó una invalidación de caché de consulta usando INSERT, UPDATE o DELETE

La consulta en sí también puede especificar que no se almacenará en la caché mediante el uso de la SQL_NO_CACHE atributo. El control de nivel de consulta es una forma eficaz de utilizar la caché de forma más óptima.

También es posible especificar que no las consultas deben almacenarse en la caché a menos que la consulta lo requiera. Para hacer esto, el query_cache_type la variable del servidor debe establecerse en 2, o DEMAND. Entonces, solo las consultas con el SQL_CACHE Los atributos se almacenan en caché.

Limitar el tamaño de la caché de consultas

Hay dos formas principales de limitar el tamaño de la caché de consultas. Primero, el tamaño total en bytes está determinado por el query_cache_size variable de servidor. Se necesitan alrededor de 40 KB para varias estructuras de caché de consultas.

El tamaño de la caché de consultas se asigna en bloques de 1024 bytes, por lo que debe establecerse en un múltiplo de 1024.

El resultado de la consulta se almacena con un tamaño de bloque mínimo de query_cache_min_res_unit. Marque dos condiciones para usar un buen valor de esta variable: caché de consultas, inserte bloques de resultados con bloqueos, cada nuevo bloque inserte bloqueo de caché de consultas, un valor pequeño aumentará los bloqueos y la fragmentación y desperdiciará menos memoria para resultados pequeños, un valor grande aumentará la memoria usa desperdiciar más memoria para resultados pequeños pero reduce bloqueos. Pruebe con su carga de trabajo para ajustar esta variable.

Si el modo estricto está habilitado, establecer el tamaño de la caché de consultas en un valor no válido provocará un error. De lo contrario, se establecerá en el valor permitido más cercano y se activará una advertencia.

SHOW VARIABLES LIKE'query_cache_size';+------------------+----------+| Variable_name    |Value|+------------------+----------+| query_cache_size |67108864|+------------------+----------+SETGLOBAL query_cache_size =8000000;
Query OK,0rows affected,1 warning (0.03 sec)SHOW VARIABLES LIKE'query_cache_size';+------------------+---------+| Variable_name    |Value|+------------------+---------+| query_cache_size |7999488|+------------------+---------+

El tamaño ideal de la caché de consultas depende en gran medida de las necesidades específicas de cada sistema. Si se establece un valor demasiado pequeño, los resultados de la consulta se eliminarán de la memoria caché cuando podrían reutilizarse más adelante. Establecer un valor demasiado alto podría resultar en un rendimiento reducido debido a la contención de bloqueo, ya que la caché de consultas se bloquea durante las actualizaciones.

La segunda forma de limitar la caché es tener un tamaño máximo para cada conjunto de resultados de la consulta. Esto evita que una sola consulta con un gran conjunto de resultados ocupe la mayor parte de la memoria disponible y elimine una gran cantidad de consultas más pequeñas de la caché. Esto está determinado por el query_cache_limit variable de servidor.

Si intenta establecer una caché de consultas que es demasiado pequeña (la cantidad depende de la arquitectura), el cambio de tamaño fallará y la caché de consultas se establecerá en cero, por ejemplo:

SETGLOBAL query_cache_size=40000;
Query OK,0rows affected,2warnings(0.03 sec)SHOWWARNINGS;+---------+------+-----------------------------------------------------------------+|Level| Code | Message                                                         |+---------+------+-----------------------------------------------------------------+| Warning |1292| Truncated incorrect query_cache_size value: '40000'|| Warning |1282| Query cache failed toset size 39936; new query cache size is0|+---------+------+-----------------------------------------------------------------+

Examinar la caché de consultas

Varias variables de estado proporcionan información sobre la caché de consultas.

SHOWSTATUSLIKE'Qcache%';+-------------------------+----------+| Variable_name           |Value|+-------------------------+----------+| Qcache_free_blocks      |1158|| Qcache_free_memory      |3760784|| Qcache_hits             |31943398|| Qcache_inserts          |42998029|| Qcache_lowmem_prunes    |34695322|| Qcache_not_cached       |652482|| Qcache_queries_in_cache |4628|| Qcache_total_blocks     |11123|+-------------------------+----------+

Qcache_inserts contiene el número de consultas agregadas a la caché de consultas, Qcache_hits contiene el número de consultas que han hecho uso de la caché de consultas, mientras que Qcache_lowmem_prunes contiene el número de consultas que se eliminaron de la caché debido a la falta de memoria.

El ejemplo anterior podría indicar un caché de bajo rendimiento. Se han agregado más consultas y se han eliminado más consultas de las que realmente se han utilizado.

Tenga en cuenta que antes de MariaDB 5.5, las consultas devueltas desde la caché de consultas no incrementaban la variable de estado Com_select, por lo que para encontrar el número total de consultas válidas ejecutadas en el servidor, agregue Com_select a Qcache_hits. A partir de MariaDB 5.5, los resultados devueltos por la caché de consultas cuentan para Com_select (ver MDEV-4981).

El complemento QUERY_CACHE_INFO crea la tabla QUERY_CACHE_INFO en INFORMATION_SCHEMA, lo que le permite examinar el contenido de la caché de consultas.

Fragmentación de la caché de consultas

La caché de consultas utiliza bloques de longitud variable y, con el tiempo, puede fragmentarse. Un alto Qcache_free_blocks relativo a Qcache_total_blocks puede indicar fragmentación. FLUSH QUERY CACHE desfragmentará la caché de consultas sin eliminar ninguna consulta:

FLUSH QUERY CACHE;

Después de esto, solo habrá un bloque libre:

SHOWSTATUSLIKE'Qcache%';+-------------------------+----------+| Variable_name           |Value|+-------------------------+----------+| Qcache_free_blocks      |1|| Qcache_free_memory      |6101576|| Qcache_hits             |31981126|| Qcache_inserts          |43002404|| Qcache_lowmem_prunes    |34696486|| Qcache_not_cached       |655607|| Qcache_queries_in_cache |4197|| Qcache_total_blocks     |8833|+-------------------------+----------+

Vaciar y deshabilitar la caché de consultas

Para vaciar o borrar todos los resultados de la caché de consultas, use RESET QUERY CACHE. FLUSH TABLES tendrá el mismo efecto.

Establecer ya sea query_cache_type o query_cache_size para 0 deshabilitará la caché de consultas, pero para liberar la mayor cantidad de recursos, configure ambos en 0 cuando desee deshabilitar el almacenamiento en caché.

Limitaciones

  • La caché de consultas debe deshabilitarse para poder utilizar OQGRAPH.
  • El motor de almacenamiento Spider no utiliza la caché de consultas (entre otros).
  • La caché de consultas también debe deshabilitarse para las versiones del clúster MariaDB Galera anteriores a “5.5.40-galera”, “10.0.14-galera” y “10.1.2”.

LOCK TABLES y la caché de consultas

La caché de consultas se puede utilizar cuando las tablas tienen un bloqueo de escritura (lo que puede parecer confuso, ya que los bloqueos de escritura deben evitar las lecturas de la tabla). Este comportamiento puede ser cambiado configurando el query_cache_wlock_invalidate variable de sistema a ON, en cuyo caso cada bloqueo de escritura invalidará la caché de consulta de la tabla. Ajuste a OFF, el valor predeterminado, significa que las consultas en caché se pueden devolver incluso cuando se mantiene un bloqueo de tabla. Por ejemplo:

1>SELECT*FROM T1
+---+| a |+---+|1|+---+-- Here the query is cached-- From another connection execute:2>LOCKTABLES T1 WRITE;-- Expected result with: query_cache_wlock_invalidate = OFF1>SELECT*FROM T1
+---+| a |+---+|1|+---+-- read from query cache-- Expected result with: query_cache_wlock_invalidate = ON1>SELECT*FROM T1
-- Waiting Table Write Lock

Transacciones y caché de consultas

La caché de consultas maneja transacciones. Internamente, un indicador (FLAGS_IN_TRANS) se establece en 0 cuando se ejecutó una consulta fuera de una transacción, y en 1 cuando la consulta estaba dentro de una transacción (BEGIN / COMMIT / ROLLBACK). Esta bandera es parte del “hash de la caché de consultas”, en otras palabras, una consulta dentro de una transacción es diferente de una consulta fuera de una transacción.

Las consultas que cambian filas (INSERT / UPDATE / DELETE / TRUNCATE) dentro de una transacción invalidarán todas las consultas de la tabla y desactivarán la caché de consultas de la tabla modificada. Las transacciones que no terminan con COMMIT / ROLLBACK comprueban que incluso sin COMMIT / ROLLBACK, la caché de consultas está desactivada para permitir el bloqueo de nivel de fila y el nivel de coherencia.

Ejemplos:

SELECT*FROM T1 <firstinsertto query cache,using FLAGS_IN_TRANS=0>+---+| a |+---+|1|+---+
BEGIN;SELECT*FROM T1 <firstinsertto query cache,using FLAGS_IN_TRANS=1>+---+| a |+---+|1|+---+
SELECT*FROM T1 <result from query cache,using FLAGS_IN_TRANS=1>+---+| a |+---+|1|+---+
INSERTINTO T1 VALUES(2);<invalidate queries fromtable T1 anddisable query cache totable T1>
SELECT*FROM T1 <don't use query cache, a normal query frominnodbtable>+---+| a |+---+|1||2|+---+
SELECT*FROM T1 <don't use query cache, a normal query frominnodbtable>+---+| a |+---+|1||2|+---+
COMMIT;<query cache is now turned onto T1 table>
SELECT*FROM T1 <firstinsertto query cache,using FLAGS_IN_TRANS=0>+---+| a |+---+|1|+---+
SELECT*FROM T1 <result from query cache,using FLAGS_IN_TRANS=0>+---+| a |+---+|1|+---+

Estructura interna de la caché de consultas

Internamente, cada indicador que puede cambiar un resultado utilizando la misma consulta es una consulta diferente. Por ejemplo, el uso del juego de caracteres latin1 y el uso del juego de caracteres utf8 con la misma consulta son tratados como consultas diferentes por la caché de consultas.

Algunos campos que diferencian las consultas son (de la estructura interna de “Query_cache_query_flags”):

  • consulta (cadena)
  • nombre del esquema de la base de datos actual (cadena)
  • bandera larga del cliente (0/1)
  • protocolo de cliente 4.1 (0/1)
  • tipo de protocolo (valor interno)
  • existen más resultados (bandera de protocolo)
  • en trans (transacción interna o no)
  • autocommit (variable de sesión de autocommit)
  • pkt_nr (bandera de protocolo)
  • cliente de juego de caracteres (variable de sesión character_set_client)
  • resultados del juego de caracteres (variable de sesión character_set_results)
  • conexión de colación (variable de sesión collation_connection)
  • límite (variable de sesión sql_select_limit)
  • zona horaria (variable de sesión time_zone)
  • sql_mode (variable de sesión sql_mode)
  • max_sort_length (variable de sesión max_sort_length)
  • group_concat_max_len (variable de sesión group_concat_max_len)
  • default_week_format (variable de sesión default_week_format)
  • div_precision_increment (variable de sesión div_precision_increment)
  • lc_time_names (variable de sesión lc_time_names)

Se puede encontrar más información viendo el código fuente (MariaDB 10.1):

Contención de tiempo de espera y mutex

Al buscar una consulta dentro de la caché de consultas, una función try_lock espera con un tiempo de espera de 50 ms. Si el bloqueo falla, la consulta no se ejecuta a través de la caché de consultas. Este tiempo de espera está codificado de forma rígida (MDEV-6766 incluir dos variables para ajustar este tiempo de espera).

Desde sql_cache.cc, función “try_lock” usando TIMEOUT:

        struct timespec waittime;
        set_timespec_nsec(waittime,(ulong)(50000000L));/* Wait for 50 msec */int res= mysql_cond_timedwait(&COND_cache_status_changed,&structure_guard_mutex,&waittime);if(res == ETIMEDOUT)break;

Al insertar una consulta dentro de la caché de consultas o al abortar una inserción de la caché de consultas (usando el comando KILL, por ejemplo), una función try_lock espera hasta que la caché de consultas regrese; en este caso no se utiliza ningún tiempo de espera.

Cuando dos procesos ejecutan la misma consulta, solo el último proceso almacena el resultado de la consulta. Todos los demás procesos aumentan la variable de estado Qcache_not_cached.

SQL_NO_CACHE y SQL_CACHE

Hay dos aspectos de la caché de consultas: colocar una consulta en la caché y recuperarla de la caché.

  1. Agregar una consulta a la caché de consultas. Esto se hace automáticamente para las consultas que se pueden almacenar en caché (consulte (Consultas almacenadas en la caché de consultas) cuando query_cache_type la variable del sistema está establecida en 1, o ON y la consulta no contiene ninguna cláusula SQL_NO_CACHE, o cuando el query_cache_type la variable del sistema está establecida en 2, o DEMANDy la consulta contiene la cláusula SQL_CACHE.
  2. Recuperando una consulta de la caché. Esto se hace después de que el servidor recibe la consulta y antes del analizador de consultas. En este caso, se debe considerar un punto:

Cuando se usa SQL_NO_CACHE, debe ser después de la primera sugerencia SELECT, por ejemplo:

SELECT SQL_NO_CACHE ....FROM(SELECT SQL_CACHE ...)AS temp_table 

en lugar de

SELECT SQL_CACHE ....FROM(SELECT SQL_NO_CACHE ...)AS temp_table 

Se comprobará la segunda consulta. La caché de consultas solo verifica si SQL_NO_CACHE / SQL_CACHE existe después del primer SELECT. (Más información en MDEV-6631)

El contenido reproducido en este sitio es propiedad de sus respectivos dueños, y MariaDB no revisa este contenido con anticipación. Los puntos de vista, la información y las opiniones expresadas por este contenido no representan necesariamente las de MariaDB o de cualquier otra parte.