Hay cuatro maneras de desencadenar el almacenamiento en caché de una consulta.
El uso de las sugerencias SQL y de mysqlnd_qc.cache_by_default = 1 se expilca más abajo. Por vafor, consulte la referenca de la función mysqlnd_qc_is_select() para una descripción del uso de una llamada de retorno, y de mysqlnd_qc_set_cache_condition() sobre cómo establecer reglas para el almacenamiento automático en caché.
Una sugerencia SQL es un comentario que sigue los estándares. Como comentario de SQL, es ignorado por la base de datos. Una consulta es considerada candidata para su almacenamiento en caché si comienza con la sugerencia SQL que habilita dicho almacenamiento o si es una sentencia SELECT.
Una consulta individual que debiera ser almacenada debe comenzar con la sugerencia SQL /*qc=on*/. Se recomienda usar la constante de PHP MYSQLND_QC_ENABLE_SWITCH en lugar del valor de cadena.
no candidata para su almacenamiento en caché y no almacenada: INSERT INTO test(id) VALUES (1)
no candidata para su almacenamiento en caché y no almacenada: SHOW ENGINES
candidata para su almacenamiento en caché pero no almacenada: SELECT id FROM test
candidata para su almacenamiento y almacenada: /*qc=on*/SELECT id FROM test
Las sentencias SELECT del ejemplo están prefijadas con la sugerencia SQL MYSQLND_QC_ENABLE_SWITCH para habilitar su almacenamiento en caché. La sugerencia SQL debe colocarse al comienzo de la cadena de consulta para habilitar el almacenamiento en caché.
Ejemplo #1 Usar la sugerencia SQL MYSQLND_QC_ENABLE_SWITCH
mysqlnd_qc.enable_qc=1
<?php
/* Conectar, crear y rellenar la tabla test */
$mysqli = new mysqli("host", "usuario", "contraseña", "esquema", "puerto", "socket");
$mysqli->query("DROP TABLE IF EXISTS test");
$mysqli->query("CREATE TABLE test(id INT)");
$mysqli->query("INSERT INTO test(id) VALUES (1), (2)");
/* Será almacenada en caché debido a la sugerencia SQL */
$inicio = microtime(true);
$res = $mysqli->query("/*" . MYSQLND_QC_ENABLE_SWITCH . "*/" . "SELECT id FROM test WHERE id = 1");
var_dump($res->fetch_assoc());
$res->free();
printf("Tiempo total de consulta no almacenada: %.6fs\n", microtime(true) - $inicio);
/* Coincidencia con la caché */
$inicio = microtime(true);
$res = $mysqli->query("/*" . MYSQLND_QC_ENABLE_SWITCH . "*/" . "SELECT id FROM test WHERE id = 1");
var_dump($res->fetch_assoc());
$res->free();
printf("Tiempo total de consulta almacenada: %.6fs\n", microtime(true) - $inicio);
?>
El resultado de los ejemplos serían algo similar a:
array(1) { ["id"]=> string(1) "1" } Tiempo total de consulta no almacenada: 0.000740s array(1) { ["id"]=> string(1) "1" } Tiempo total de consulta almacenada: 0.000098s
Si no se configura nada más, como es el caso del ejemplo de esta guía rápida, el complemento usará en gestor de almacenamiento interno default. El gestor de almacenamiento default utiliza la memoria del proceso para mantener una entrada de la caché. Dependiendo del modelo de desarrollo de PHP, un proceso de PHP podría servir una o más peticiones web. Por favor, consulte el manual del servidor web para más detalles. Los detalles son irrelevantes para los ejemplos dados en esta guía rápida.
El complemento de caché de consultas almacenará todas las consultas sin considerar si la cadena de consulta comienza con la sugerencia SQL que habilita dicho almacenamiento, si la directiva de configuración de PHP mysqlnd_qc.cache_by_default está establecida a 1. El ajuste mysqlnd_qc.cache_by_default es evaluado por el núcleo del complemento de caché de consultas. Ni el gestor de almacenamiento interno ni uno definido por el usuario pueden sobrescribir el ajuste.
La sugerencia SQL /*qc=off*/ se puede usar para deshabilitar el almacenamiento en caché de consultas individuales si mysqlnd_qc.cache_by_default = 1. Se recomienda usar la constante de PHP MYSQLND_QC_DISABLE_SWITCH en lugar del valor de cadena.
Ejemplo #2 Usar la sugerencia SQL MYSQLND_QC_DISABLE_SWITCH
mysqlnd_qc.enable_qc=1 mysqlnd_qc.cache_by_default=1
<?php
/* Conectar, crear y rellenar la tabla test */
$mysqli = new mysqli("host", "usuario", "contraseña", "esquema", "puerto", "socket");
$mysqli->query("DROP TABLE IF EXISTS test");
$mysqli->query("CREATE TABLE test(id INT)");
$mysqli->query("INSERT INTO test(id) VALUES (1), (2)");
/* Será almacenada aunque no esté presente ninguna sugerencia SQL ya que mysqlnd_qc.cache_by_default = 1*/
$res = $mysqli->query("SELECT id FROM test WHERE id = 1");
var_dump($res->fetch_assoc());
$res->free();
$mysqli->query("DELETE FROM test WHERE id = 1");
/* Coincidencia con la caché - ¡sin invalidación automática y aún válida! */
$res = $mysqli->query("SELECT id FROM test WHERE id = 1");
var_dump($res->fetch_assoc());
$res->free();
/* No coincide con la caché - la consulta no debe almacenarse debido a la sugerencia SQL */
$res = $mysqli->query("/*" . MYSQLND_QC_DISABLE_SWITCH . "*/SELECT id FROM test WHERE id = 1");
var_dump($res->fetch_assoc());
$res->free();
?>
El resultado de los ejemplos serían:
array(1) { ["id"]=> string(1) "1" } array(1) { ["id"]=> string(1) "1" } NULL
PECL/mysqlnd_qc prohíbe el almacenamiento en la caché de sentencias donde al menos una columna del conjunto de resultados de dichas sentencias no muestren el nombre de la tabla en sus metadatos de forma predeterminada. Éste normalmente es el caso para las columnas originadas desde funciones SQL tales como NOW() o LAST_INSERT_ID(). La política se dirige a prevenir fallos si se usa el almacenamiento por omisión.
Ejemplo #3 Ejemplo que muestra qué tipos de sentencias no son almacenadas en la caché
mysqlnd_qc.enable_qc=1 mysqlnd_qc.cache_by_default=1
<?php
/* Conectar, crear y rellenar la tabla test */
$mysqli = new mysqli("host", "usuario", "contraseña", "esquema", "puerto", "socket");
$mysqli->query("DROP TABLE IF EXISTS test");
$mysqli->query("CREATE TABLE test(id INT)");
$mysqli->query("INSERT INTO test(id) VALUES (1)");
for ($i = 0; $i < 3; $i++) {
$inicio = microtime(true);
/* Nota: la sentencia no será almacenada debido al uso de NOW() */
$res = $mysqli->query("SELECT id, NOW() AS _time FROM test");
$fila = $res->fetch_assoc();
/* volcar resultados */
var_dump($fila);
printf("Tiempo total: %.6fs\n", microtime(true) - $inicio);
/* pausar durante un segundo */
sleep(1);
}
?>
El resultado de los ejemplos serían algo similar a:
array(2) { ["id"]=> string(1) "1" ["_time"]=> string(19) "2012-01-11 15:43:10" } Tiempo total: 0.000540s array(2) { ["id"]=> string(1) "1" ["_time"]=> string(19) "2012-01-11 15:43:11" } Tiempo total: 0.000555s array(2) { ["id"]=> string(1) "1" ["_time"]=> string(19) "2012-01-11 15:43:12" } Tiempo total: 0.000549s
Es posible habilitar el almacenamiento en caché para todas las sentecias incluyendo aquellas que tienen columnas en su conjunto de resultados para las cuales MySQL no notifica una tabla, como la sentencia del ejemplo. Se ha de establecer mysqlnd_qc.cache_no_table = 1 para habilitar el almacenamiento en caché de tales sentencias. Por favor, observe la diferencia en los tiempos medidos para los ejemplos de arriba y de abajo.
Ejemplo #4 Habilitar el almacenamiento en caché de todas las sentencias usando el ajuste ini mysqlnd_qc.cache_no_table
mysqlnd_qc.enable_qc=1 mysqlnd_qc.cache_by_default=1 mysqlnd_qc.cache_no_table=1
<?php
/* Conectar, crear y rellenar la tabla test */
$mysqli = new mysqli("host", "usuario", "contraseña", "esquema", "puerto", "socket");
$mysqli->query("DROP TABLE IF EXISTS test");
$mysqli->query("CREATE TABLE test(id INT)");
$mysqli->query("INSERT INTO test(id) VALUES (1)");
for ($i = 0; $i < 3; $i++) {
$inicio = microtime(true);
/* Nota: la sentencia no será almacenada debido al uso de NOW() */
$res = $mysqli->query("SELECT id, NOW() AS _time FROM test");
$fila = $res->fetch_assoc();
/* volcar resultados */
var_dump($fila);
printf("Tiempo total: %.6fs\n", microtime(true) - $inicio);
/* pausar durante un segundo */
sleep(1);
}
?>
El resultado de los ejemplos serían algo similar a:
array(2) { ["id"]=> string(1) "1" ["_time"]=> string(19) "2012-01-11 15:47:45" } Tiempo total: 0.000546s array(2) { ["id"]=> string(1) "1" ["_time"]=> string(19) "2012-01-11 15:47:45" } Tiempo total: 0.000187s array(2) { ["id"]=> string(1) "1" ["_time"]=> string(19) "2012-01-11 15:47:45" } Tiempo total: 0.000167s
Nota:
Aunque mysqlnd_qc.cache_no_table = 1 haya sido creado para usarlo con mysqlnd_qc.cache_by_default = 1 está vilculado a él. El complemento evaluará mysqlnd_qc.cache_no_table siempre que se vaya a almacenar una consulta, sin importar si el almacenameinto en caché ha sido habilitado usando una sugerencia SQL o cualquier otra medida.