web-dev-qa-db-ja.com

クラッシュ不可DBクエリを実行する正しい方法

コードを考えてください

function getNow() {
    global $wpdb;

    $now = $wpdb->get_var("SELECT NOW()");

    $wpdb->flush();

    return $now;
}

get_varメソッドのキャッシュ効果を避けるために上記の方法を使用しています。関数を実行すると、常に同じ結果が得られます。例えば、

echo getNow();
sleep(10);
echo getNow(); // Same result as above

質問:

  1. キャッシュ効果を避けるために上記の関数を書くもっと良い方法はありますか?
  2. なぜ$wpdbは最後の結果のみをキャッシュしますが、全てのクエリの結果が同じリクエストになるわけではないのですか?最後のクエリだけでは少しやり過ぎるようですね。
1
Yoga

私はあなたが何について話しているのか完全にはわからないので、頭に浮かぶ可能性について言及します。

たぶんこれ...

// Keep track of the last query for debug..
$this->last_query = $query;

http://core.trac.wordpress.org/browser/tags/3.5.2/wp-includes/wp-db.php#L1195

...あなたが話しているのは…もしそうなら、あなたのコードは単に$wpdbプロパティをflushまたは空の値にリセットする nullメソッド を実行するだけです。それは何も「妨げる」のではなく、「キャッシング」のようにも見えません。 PHPにもう少し作業を追加するだけです。

それとも多分あなたはこれについて話している:

$this->result = @mysql_query( $query, $this->dbh );

http://core.trac.wordpress.org/browser/tags/3.5.2/wp-includes/wp-db.php#L1200

しかし、それが「キャッシング」としてどのように評価されるのかわかりません。クラスは結果を取得し、それらをどこかに配置する必要があります。それどこか$this->resultsです。

それとも多分あなたはこれについて話している:

get_var関数はデータベースから単一の変数を返します。変数は1つしか返されませんが、クエリの結果全体は後で使用するためにキャッシュされます。結果が見つからない場合はNULLを返します。

http://codex.wordpress.org/Class_Reference/wpdb#SELECT_a_Variable

$wpdb->get_var("SELECT ID FROM {$wpdb->posts}");を試した場合、データベースの行に等しい結果セットが得られますが、get_varは1つの結果のみを返します。他の結果はまだオブジェクトに保持されています。あなたが偶然(少し)後でそれらの結果を必要とするならば、それらは別の質問なしで利用可能です。

var_dump($wpdb->get_var("SELECT ID FROM {$wpdb->posts}"));
var_dump($wpdb->last_result);

私がそれを必要としたことがないけれども、これは私の心に本当に「キャッシング」として数える唯一のものです。いずれにしてもそのクエリは単一行のみを返すので、それはあなたのクエリと実質的な違いはありません。


上記の関数を書くもっと良い方法はありますか?

特に$wpdb->flush()のようなクエリでは、上記のいずれのケースでも利点はあまり見られないので、"SELECT NOW()"を省略してください。次のクエリが実行されるとすぐに$wpdb->flushが実行されます。

$now変数を設定してからそれをreturn変数に設定する理由はありません。 returningする前に$nowデータの健全性チェックを追加するつもりでない限り、クエリから直接returnを使用してください。

なぜ$ wpdbは最後の結果のみをキャッシュしますが、すべてのクエリの結果が同じリクエストになるわけではないのですか?最後のクエリだけでは少しやり過ぎるようですね。

コーデックスが「キャッシュ」という用語を使用しているにもかかわらず、私はこれのほとんどが「キャッシュ」としてカウントされるかどうかはわかりませんが、その点については議論しません。それがまったく1つであれば、それはごくわずかなキャッシュです。 「キャッシュ」は、ほとんど$wpdbがどのように機能するかのアーティファクトです。

リクエスト内のすべてのクエリを「キャッシュ」することに関しては、少なくともいくつかのサーバでそれを試した場合、メモリの問題が発生することが予想されます。 4つか5つの非常に大きな結果セットがすべてメモリを消費すると想像してください。

$wpdbは実際にはデータベースへの比較的単純なインターフェースです。それは便利ですが、私はあなたがそれをそれのように扱うか、またはそれがそれ以上であると期待しているかもしれないと思います。それはクエリを実行し、それ自身の使用とデバッグのためにわずかな情報を保存します、そして基本的な接続情報とテーブル名ショートカット($wpdb->posts)のような他の基本的なもの以外の別のクエリが実行されるとき終わった。これはグローバルクエリマネージャやクエリキャッシュではありません。

更新された説明に基づいて、私は走った:

function getNow() {
    global $wpdb;
    $now = $wpdb->get_var("SELECT NOW()");
    $wpdb->flush();
    return $now;
}

echo '<pre>';
echo getNow();
echo "\n";
sleep(10);
echo getNow(); // Same result as above
echo '</pre>';
die;

そして得た:

2013-06-25 10:37:06
2013-06-25 10:37:16

実行するたびに、2つの結果は10秒異なります。

それから私は$wpdb->flush();をコメントアウトして試しました。同じ結果です。ソースからわかるように$wpdb->flush();はとにかく すべてのクエリの前に実行されるので、これは理にかなっています

あなたが見ている効果は、$wpdbの内部操作の結果ではありません。他にもいくつかのキャッシングメカニズムがあります。

1
s_ha_dum