web-dev-qa-db-ja.com

Wpdbクラスを介して実行されたクエリはキャッシュされますか?

WordPressがどのようにクエリをキャッシュするのかわかりません。私は、wpdbクラスを介してクエリを実行すると必ずそれがキャッシュされるという印象を受けました。たとえば、[行の選択]および[変数の選択]の下のコーデックスでは、後で使用するためにクエリ全体がキャッシュされます。それは、別のクエリでより多くのデータが要求され、パーシャルまたは完全な結果がすでにwpdbキャッシュにある場合、それらが使用されてクエリが実行されないことを意味します(完全な結果が既にキャッシュにある場合)。理解は正しいですか?

何かをしようとしていたところ、キャッシュを使用できないことがわかりました。参考のために、私は現在のユーザーが行った最近のコメントをリストしていました。 get_comments()を使いましたが、結果にはpost idしかないので、それらを表示するためにループの中でget_the_title()を使いました。明らかにこれは問い合わせの点では高価です、それで私はget_the_title()が実際の問い合わせをしないように事前に問い合わせることによってpostテーブルの必要な行をキャッシュすることができますが。私は何かをしました

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

しかし、それは役に立ちませんでした。 get_the_title()はまだ問い合わせをしています。たぶん、WP Cacheのしくみを誤解している私がいます。だから私は間違っているところ?

これは参照用の完全なコードです - http://ashfame.Pastebin.com/BpxjHiQr

6
Ashfame

いいえ、そのようには動作しません。データベース関連のキャッシュは最小限であり、ほとんどの場合、単一ページのロード中にまったく同じクエリを使用することをカバーしています。

データベースおよび/または計算集約的な結果を永続的にキャッシュする最良の方法は、 トランジェントAPI を使用して結果を適切な期間保存することです。

6
Rarst

ドキュメントは、クエリからの出力はその特定のリクエストに対してのみキャッシュされることを示唆していました - そのためおそらくWordPressはMySQL上でバッファされたクエリをしています。

私の場合は、wp_cache_ *関数を使用しました - http://codex.wordpress.org/Class_Reference/WP_Object_Cacheを参照してください

コード例:

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

@GingerDogによる解決策は完璧に機能しましたが、1ページのリフレッシュでのみ実現されました。セッションのクエリ結果をキャッシュしたい場合は、$ _ SESSIONを使用して同様のソリューションを使用できます(Transients APIはセッションとマシン間で機能します)。

$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