web-dev-qa-db-fra.com

Une requête exécutée via la classe wpdb est-elle mise en cache?

Je ne suis pas sûr de savoir comment WordPress cache les requêtes. J'ai eu l'impression que chaque fois que j'exécute une requête via la classe wpdb, celle-ci est mise en cache. Par exemple, dans le codex sous Sélectionner une ligne et Sélectionner une variable, il est indiqué que la requête entière est mise en cache pour une utilisation ultérieure. Et je pense que cela signifie que si plus de données sont demandées dans une autre requête, si des partiels ou des résultats complets sont déjà dans le cache wpdb, ils sont utilisés et une requête ne se produit pas (dans le cas de résultats complets déjà en cache). Ai-je raison de comprendre?

J'essayais quelque chose et j'ai constaté que je ne pouvais pas utiliser le cache. Pour référence, je listais les commentaires récents de l'utilisateur actuel. J'ai utilisé get_comments() mais comme il n'a que post ID dans les résultats, j'ai utilisé get_the_title() dans la boucle pour les afficher. Évidemment, cela coûte cher en termes de requête. Je pense donc pouvoir mettre en cache les lignes requises de la table post en les interrogeant au préalable afin que get_the_title() ne fasse aucune requête. J'ai fait quelque chose comme

$query = implode( ' OR ID = ', $collect_post_ids );
$query = 'SELECT * FROM '.$wpdb->prefix.'posts WHERE ID = '.$query.';';
$wpdb->get_results( $query ); // just cache it

mais cela n'a pas aidé. get_the_title() est toujours en train de faire des requêtes. C'est probablement moi qui ai mal compris comment fonctionne WP Cache. Alors où je me trompe?

Voici le code complet pour référence - http://ashfame.Pastebin.com/BpxjHiQr

6
Ashfame

Non, ça ne marche pas comme ça. La mise en cache liée à la base de données est minimale et couvre principalement l’utilisation précise des mêmes requêtes lors du chargement d’une page.

Le meilleur moyen de mettre en cache de manière persistante des résultats intensifs en bases de données et/ou en calculs consiste à utiliser API de transitoires pour stocker les résultats pendant une période d'ajustement.

6
Rarst

Les documents suggéraient que la sortie d'une requête était mise en cache uniquement pour cette requête spécifique. Par conséquent, WordPress effectue probablement une requête en mémoire tampon sur MySQL.

Dans mon cas, j'ai utilisé les fonctions wp_cache_ * - voir http://codex.wordpress.org/Class_Reference/WP_Object_Cache

Exemple de code:

sql = "
    SELECT {$wpdb->posts}.* FROM {$wpdb->posts}
    LEFT JOIN {$wpdb->term_relationships} ON ({$wpdb->posts}.ID = {$wpdb->term_relationships}.object_id)
    LEFT JOIN {$wpdb->term_taxonomy} ON ({$wpdb->term_relationships}.term_taxonomy_id = {$wpdb->term_taxonomy}.term_taxonomy_id)
    WHERE ({$wpdb->term_taxonomy}.taxonomy = 'category' AND {$wpdb->term_taxonomy}.term_id = 9849 )
    AND
    {$wpdb->posts}.post_status = 'publish' AND
    {$wpdb->posts}.post_type = 'post' ORDER BY {$wpdb->posts}.post_title ASC";

$posts = wp_cache_get(md5($sql), 'somerandomkey');
if($posts === false) {
    $posts = $wpdb->get_results($sql, OBJECT);
    wp_cache_add(md5($sql), $posts, 'somerandomkey');
}

if(empty($posts)) {
    echo "<p>No results found </p>";
}
3
David Goodwin

La solution donnée par @GingerDog fonctionne parfaitement, mais ne le fait que lors d'une actualisation d'une seule page. Si vous souhaitez mettre en cache le résultat de votre requête pour une session, vous pouvez utiliser une solution similaire avec $ _SESSION (alors que l'API Transients fonctionne avec des sessions et des ordinateurs).

$sQuery = "SELECT `ID`,`post_name` FROM `wp_posts` WHERE `post_type` = 'attachment' AND `post_name` LIKE 'foobar%'";
$sQueryMD5 = md5($sQuery);
if (isset($_SESSION[$sQueryMD5])){
    $aResult = $_SESSION[$sQueryMD5];
} else { // search wp_posts
    $aResult = $wpdb->get_results($sQuery, OBJECT);
    $_SESSION[$sQueryMD5] = $aResult;
}
0
Sjeiti