Una sentencia debería ser considerada para ser almacenada en la caché si se ejecuta a menudo y tiene un tiempo de ejecución largo. Las candidatas se buscan creando una lista de sentencias ordenadas por el producto del número de ejecuciones multiplicado por el tiempo de ejecución de la sentencia. La función mysqlnd_qc_get_query_trace_log() devuelve un registro de consultas que ayudan con la tarea.
Recopilar el rastreo de una consulta es una operación lenta. Por lo tanto, está deshabilitada de forma predeterminada.
La directiva de configuración de PHP
mysqlnd_qc.collect_query_trace
se usa para habilitarla. El rastreo de la función contiene una entrada para cada
consulta emitida antes de llamar a la función.
Ejemplo #1 Recopilar un rastreo de consulta
mysqlnd_qc.enable_qc=1 mysqlnd_qc.collect_query_trace=1
<?php
/* conectarse a MySQL */
$mysqli = new mysqli("host", "usuario", "contraseña", "esquema", "puerto", "socket");
/* consultas varias para rellenar el rastreo de consultas */
for ($i = 0; $i < 2; $i++) {
$res = $mysqli->query("SELECT 1 AS _one FROM DUAL");
$res->free();
}
/* volcar el rastreo */
var_dump(mysqlnd_qc_get_query_trace_log());
?>
El resultado de los ejemplos sería:
array(2) { [0]=> array(8) { ["query"]=> string(26) "SELECT 1 AS _one FROM DUAL" ["origin"]=> string(102) "#0 qc.php(7): mysqli->query('SELECT 1 AS _on...') #1 {main}" ["run_time"]=> int(0) ["store_time"]=> int(25) ["eligible_for_caching"]=> bool(false) ["no_table"]=> bool(false) ["was_added"]=> bool(false) ["was_already_in_cache"]=> bool(false) } [1]=> array(8) { ["query"]=> string(26) "SELECT 1 AS _one FROM DUAL" ["origin"]=> string(102) "#0 qc.php(7): mysqli->query('SELECT 1 AS _on...') #1 {main}" ["run_time"]=> int(0) ["store_time"]=> int(8) ["eligible_for_caching"]=> bool(false) ["no_table"]=> bool(false) ["was_added"]=> bool(false) ["was_already_in_cache"]=> bool(false) } }
El rastreo se da con información desordenada. También se dan
los tiempos y el origen de la llamada de la consulta. La propiedad 'origin'
contiene un código de búsqueda de rastros para identificar el origen de la consulta.
La profundidad de la búsqueda de rastros se puede limitar con
la directiva de configuración de PHP
mysqlnd_qc.query_trace_bt_depth
.
La profundidad predeterminada es 3
.
Ejemplo #2 Establecer la profundidad de la búsqueda de rastros con el ajuste ini mysqlnd_qc.query_trace_bt_depth
mysqlnd_qc.enable_qc=1 mysqlnd_qc.collect_query_trace=1
<?php
/* conectarse a MySQL */
$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)");
/* consultas varias para rellenar el rastreo de consultas */
for ($i = 0; $i < 3; $i++) {
$res = $mysqli->query("SELECT id FROM test WHERE id = " . $mysqli->real_escape_string($i));
$res->free();
}
$rastreo = mysqlnd_qc_get_query_trace_log();
$resumen = array();
foreach ($rastreo as $entrada) {
if (!isset($resumen[$entrada['query']])) {
$resumen[$entrada['query']] = array(
"executions" => 1,
"time" => $entrada['run_time'] + $entrada['store_time'],
);
} else {
$resumen[$entrada['query']]['executions']++;
$resumen[$entrada['query']]['time'] += $entrada['run_time'] + $entrada['store_time'];
}
}
foreach ($resumen as $consulta => $detalles) {
printf("%45s: %5dms (%dx)\n",
$consulta, $detalles['time'], $detalles['executions']);
}
?>
El resultado de los ejemplos sería algo similar a:
DROP TABLE IF EXISTS test: 0ms (1x) CREATE TABLE test(id INT): 0ms (1x) INSERT INTO test(id) VALUES (1), (2), (3): 0ms (1x) SELECT id FROM test WHERE id = 0: 25ms (1x) SELECT id FROM test WHERE id = 1: 10ms (1x) SELECT id FROM test WHERE id = 2: 9ms (1x)