Trouver des candidats à la mise en cache

Une requête doit être considérée comme pouvant être mise en cache si elle est souvent exécutée et qu'elle a un temps d'exécution élevé. Les candidats sont trouvés en créant une liste de requêtes triées par le produit du nombre d'exécutions, multiplié par le temps d'exécution de la requête. La fonction mysqlnd_qc_get_query_trace_log() retourne une trace permettant d'aider dans cette tâche.

La collecte d'une trace de requête est une opération lente. Aussi, cette opération est désactivée par défaut. La directive de configuration PHP mysqlnd_qc.collect_query_trace est utilisée pour l'activer. Les traces des fonctions contiennent une entrée pour chaque requête émise avant l'appel à la fonction.

Exemple #1 Collecte d'une requête de traçage

<?php
/* connexion à MySQL */
$mysqli = new mysqli("host", "user", "password", "schema", "port", "socket");

/* quelques requêtes pour remplir les traces de requêtes */
for ($i = 0; $i < 2; $i++) {
  $res = $mysqli->query("SELECT 1 AS _one FROM DUAL");
  $res->free();
}

/* Affichage des traces */
var_dump(mysqlnd_qc_get_query_trace_log());
?>
<?php
/* connexion à MySQL */
$mysqli = new mysqli("host", "user", "password", "schema", "port", "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)");

/* quelques requêtes pour remplir les traces */
for ($i = 0; $i < 3; $i++) {
  $res = $mysqli->query("SELECT id FROM test WHERE id = " . $mysqli->real_escape_string($i));
  $res->free();
}

$trace = mysqlnd_qc_get_query_trace_log();
$summary = array();
foreach ($trace as $entry) {
  if (!isset($summary[$entry['query']])) {
	$summary[$entry['query']] = array(
	  "executions" => 1,
	  "time"	   => $entry['run_time'] + $entry['store_time'],
	);
  } else {
	$summary[$entry['query']]['executions']++;
	$summary[$entry['query']]['time'] += $entry['run_time'] + $entry['store_time'];
 }
}
foreach ($summary as $query => $details) {
  printf("%45s: %5dms (%dx)\n",
   $query, $details['time'], $details['executions']);
}
?>

Les exemples ci-dessus vont afficher :

                    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)

LoadingChargement en cours