Almacenamiento en caché basado en patrones

Una aplicación tiene tres opciones para indicarle a PECL/mysqlnd_qc si será usada una sentencia en particular. El enfoque más básico es almacenar en caché todas las sentencias estableciendo mysqlnd_qc.cache_by_default = 1. Este enfoque a menudo es poco práctico, aunque habilita a los usuarios realizar una estimación rápida sobre las ganancias de rendimiento máximas de la caché. Una aplicación diseñada para usar una caché podría prefijar las sentencias seleccionadas con las sugerencias SQL apropiadas. Sin embargo, alterar el código fuente de una aplicación podría no ser siempre posible o deseado, por ejemplo, para evitar problemas con actualizaciones de software. Por ello, PECL/mysqlnd_qc permite establecer una llamada de retorno que decida si una consulta será almacenada en caché.

La llamada de retorno se instala con la función mysqlnd_qc_set_is_select(). A la llamada de retorno se le proporciona una cadena de sentencia de cada sentencia inspeccionada por el complemento. Luego, la llamada de retorno puede decidir si almacenará en caché la función. La llamada de retonro debe devolver FALSE si la sentencia no será almacenada en caché. Un valor de retorno de TRUE hace que el complemento intente añadir la sentencia a la caché. A la entrada de la caché se le dará el TTL predeterminado ( mysqlnd_qc.ttl). Si la llamada de retorno devuelve un valor numérico se usará éste como el TTL en lugar del predeterminado global.

Ejemplo #1 Establecer una llamada de retorno con mysqlnd_qc_set_is_select()

mysqlnd_qc.enable_qc=1
mysqlnd_qc.collect_statistics=1
<?php
/* llamada de retorno que decice si una consulta se almacena en caché */
function is_select($consulta) {
    static 
$patrones = array(
      
/* true - usar lo predetermiando por mysqlnd_qc.ttl */
      
"@SELECT\s+.*\s+FROM\s+test@ismU" => true,
      
/* 3 - usar TTL = 3 segundos */
      
"@SELECT\s+.*\s+FROM\s+news@ismU" => 3
    
);

    
/* comprobar si la consulta coincide con el patrón */
    
foreach ($patrones as $patrón => $ttl) {
        if (
preg_match($patrón$consulta)) {
            
printf("is_select(%45s): almacenada\n"$consulta);
            return 
$ttl;
        }
    }
    
printf("is_select(%45s): no almacenada\n"$consulta);
    return 
false;
}
/* instalar la llamada de retorno */
mysqlnd_qc_set_is_select("is_select");

/* 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), (3)");

/* colocada en la caché */
$mysqli->query("SELECT id FROM test WHERE id = 1");
/* coincidencia con la caché */
$mysqli->query("SELECT id FROM test WHERE id = 1");
/* colocada en la caché */
$mysqli->query("SELECT * FROM test");

$estadísticas mysqlnd_qc_get_core_stats();
printf("Colocada en caché: %d\n"$estadísticas['cache_put']);
printf("Coincidencia con la caché: %d\n"$estadísticas['cache_hit']);
?>

El resultado de los ejemplos sería algo similar a:

is_select(                    DROP TABLE IF EXISTS test): no almacenada
is_select(                    CREATE TABLE test(id INT)): no almacenada
is_select(    INSERT INTO test(id) VALUES (1), (2), (3)): no almacenada
is_select(             SELECT id FROM test WHERE id = 1): almacenada
is_select(             SELECT id FROM test WHERE id = 1): almacenada
is_select(                           SELECT * FROM test): almacenada
Colocada en caché: 2
Coincidencia con la caché: 1

La llamada de retorno del ejemplo comprueba si una cadena de sentencia coincide con un patrón. Si éste es el caso, devuelve TRUE para almacenar en caché la consulta usando el TTL global o un TTL alternativo.

Para minimizar los cambios en la aplicación, la llamada de retorno puede colocarse y registrarse en un fichero autoantepuesto.