1

Yii フレームワーク 1.1.12 を使用してデータベースから取得した結果をキャッシュしようとしています。要するに私がやっていることは次のとおりです。

public static function getCategories()
{
    if (self::$_categories !== null)
        return self::$_categories;

    print "Getting categories...";    
    self::$_categories = Yii::app()->cache->get("categoriesList");
    if (self::$_categories === false)
    {
        $sql = "SELECT id, parent_id, name FROM {{category}} WHERE id > 0 AND is_deleted = 0";
        $categoriesList = Yii::app()->db->createCommand($sql)->queryAll();

        // Doing some work with $categoriesList and obtaining self::$_categories as the result
        // ...

        $dependency = new CDbCacheDependency("SELECT MAX(update_time) FROM {{category}}");
        Yii::app()->cache->set("categoriesList", self::$_categories, 3600, $dependency);
    }

    return self::$_categories;
}

プロファイリング ツールを使用すると、すべてが機能していることがわかります。最初に両方のクエリが実行されます (各クエリは 1 回):

SELECT MAX(update_time) FROM arrenda_category
SELECT id, parent_id, name FROM arrenda_category WHERE id > 0 AND is_deleted = 0

それ以降のリクエストでは、最初のリクエストのみが実行されます。

update_time問題は、テーブル内の最大値を増やしarrenda_category(独自の編集スクリプトを使用していなくても - MySQL コマンド ラインから直接)、ページを更新すると、SELECT MAX(update_time) FROM arrenda_categoryクエリの数が 2 になります。さらに更新すると、再度 1 回しか実行されません。興味深いことに、キャッシュをクリアすると、SELECT MAX(...) ...クエリも 1 回実行されます。

そのため、条件の変更時にキャッシュ依存クラスのクエリが 2 回実行される理由がわかりません。私のコードに何か問題がありますか?

SELECT MAX(update_time) FROM arrenda_categoryPS上記の関数でのみ実行できると確信しています。print "Getting categories..."また、ページ要求ごとに 1 回行に到達することもわかります。

4

1 に答える 1

3

はい。期待されています。

説明

データがすでにキャッシュにあるとします。また、関数を呼び出すとgetCategories() 、行Yii::app()->cache->get("categoriesList")は依存関係クエリを実行して、データが変更されているかどうかを確認します。変更されないため、クエリは1回だけ実行されます。

ここで、update_time値を外部で変更し(または、アプリで別のコードを使用して)、getCategories()もう一度呼び出します。

  1. この行Yii::app()->cache->get("categoriesList")は依存関係クエリを実行して、キャッシュ内のデータが有効かどうかを確認します。データが無効であることが検出され、falseが返されます
  2. 次に、クエリSELECT id, parent_id, name FROM {{category}} WHERE id > 0 AND is_deleted = 0が実行され、データベースから更新されたデータがフェッチされます。
  3. Yii::app()->cache->set("categoriesList", self::$_categories, 3600, $dependency); AGAINは依存関係クエリを実行して、結果がデータとともに保存されてSELECT MAX(update_time) FROM {{category}}いる最新のものを取得します。MAX(update_time)そのため、クエリは2回実行されます。

つまり、重要なのは、値をキャッシュするたびに、依存関係が変更されているかどうかを確認するための後続のクエリでset()必要になるため、依存関係の値を一緒に保存する必要があるということです。get()

PS:さらに明確にしたい場合は、アプリケーションコンポーネントのset()関数のソースコードを確認してください。クラスの関数を呼び出し、次にそれを呼び出して、依存関係クエリを実行します。cacheevaluateDependency()CDbCacheDependancygenerateDependentData()

于 2012-10-21T07:37:01.063 に答える