## 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

    mysqlnd_qc.enable_qc=1
    mysqlnd_qc.collect_query_trace=1

`<?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());
?>`

Les exemples ci-dessus vont afficher :

    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)
      }
    }

D'autres informations sont fournies dans les trâces. Parmi elles, les horaires et l'origine de l'appel à la requête. La propriété origin contient une trace du code pour identifier la source de la requête. La profondeur de la trace du code peut être limitée avec la directive de configuration PHP mysqlnd_qc.query_trace_bt_depth. La profondeur par défaut est 3.

Exemple #2 Définir la profondeur des traces avec l'option de configuration ini mysqlnd_qc.query_trace_bt_depth

    mysqlnd_qc.enable_qc=1
    mysqlnd_qc.collect_query_trace=1

`<?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)