2017-02-21 3 views
0

Railsは実際にクエリ結果をキャッシュしますか? The documentationは、同じクエリが同じ要求に二回実行されないであろうと述べている:Railsは本当にデータベースクエリをキャッシュしますか?

1.7 SQLのキャッシングは

同じクエリがデータベースに対して実行された二回目は、実際にデータベースをヒットするつもりはありません。結果がクエリから返された最初のときには、クエリキャッシュ(メモリ内)に格納され、2回目はメモリから取得されます。

私はRailsは、実際にクエリをキャッシュすることを証明する実験を行った:私は、各User.find(1)に対して同じ結果になるだろう

def test 
    data = "" 
    User.find(1).update(first_name: 'Suwir Suwirr') 
    data << User.find(1).first_name 
    data << "\n" 

    User.find(1).update(first_name: 'Pengguna') 
    data << User.find(1).first_name 
    data << "\n" 

    render plain: data 
    end 

結果がキャッシュされている場合は、を。しかし、実際にはRailsはクエリをキャッシュしませんでした。

Suwir Suwirr 
Pengguna 

しかし、コンソールは、それがをキャッシュされたことを言う:私は、それが「キャッシュされた」ので、updateが結果に反映されません期待していた(CACHE単語をハイライトしてください)

Started GET "/diag/test" for 10.0.2.2 at 2017-02-21 10:30:16 +0700 
Processing by DiagController#test as HTML 
    User Load (0.7ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 4], ["LIMIT", 1]] 
    User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]] 
    (0.1ms) BEGIN 
    SQL (0.4ms) UPDATE "users" SET "first_name" = $1, "updated_at" = $2 WHERE "users"."id" = $3 [["first_name", "Suwir Suwirr"], ["updated_at", 2017-02-21 03:30:16 UTC], ["id", 1]] 
    (16.5ms) COMMIT 
    User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]] 
    CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]] 
    (0.1ms) BEGIN 
    SQL (0.3ms) UPDATE "users" SET "first_name" = $1, "updated_at" = $2 WHERE "users"."id" = $3 [["first_name", "Pengguna"], ["updated_at", 2017-02-21 03:30:16 UTC], ["id", 1]] 
    (0.9ms) COMMIT 
    User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]] 
    Rendering text template 
    Rendered text template (0.0ms) 
Completed 200 OK in 380ms (Views: 3.5ms | ActiveRecord: 21.9ms) 

だから私の質問は、実際には、クエリの結果をキャッシュしますか?または、いくつかのリクエストでいくつかのクエリ結果のみですか?

更新:バッチ#update_all

を使用して、私は、クエリロジックを「だます」ために別の実験を行いました。今、Railsはクエリを「キャッシュ」しません。なぜこの現象が起こるのでしょうか?

# Controller 
    def test 
    data = "" 
    User.where(id: 1).update_all(first_name: 'Suwir Suwirr') 
    data << User.find(1).first_name 
    data << "\n" 

    User.where(id: 1).update_all(first_name: 'Pengguna') 
    data << User.find(1).first_name 
    data << "\n" 

    logger.info 'hi' 

    render plain: data 
    end 

# Console 
Started GET "/diag/test" for 10.0.2.2 at 2017-02-21 10:45:43 +0700 
Processing by DiagController#test as HTML 
    User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 4], ["LIMIT", 1]] 
    SQL (13.8ms) UPDATE "users" SET "first_name" = 'Suwir Suwirr' WHERE "users"."id" = $1 [["id", 1]] 
    User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]] 
    SQL (2.9ms) UPDATE "users" SET "first_name" = 'Pengguna' WHERE "users"."id" = $1 [["id", 1]] 
    User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]] 
hi 
    Rendering text template 
    Rendered text template (0.0ms) 
Completed 200 OK in 28ms (Views: 0.8ms | ActiveRecord: 17.8ms) 

# Browser result 
Suwir Suwirr 
Pengguna 
+1

クエリがキャッシュされます(選択、検索、検索)。更新と破棄はキャッシュされません。 – coderhs

答えて

1

私は愚かでした。

はい、レールは実際にクエリをキャッシュしますが、updatedestroyはクエリキャッシュを無効にします。 update_allは基本的に各レコードをupdateで繰り返しています。

私は、実際にActiveRecordクエリメカニズムを「欺く」ことによって実験を試みました。そして、はい、それは動作します。

# Controller 
    def test 
    data = "" 
    ActiveRecord::Base.connection.execute('UPDATE "users" SET "first_name" = \'Suwir Suwirr\' WHERE "users"."id" = 1') 
    data << User.find(1).first_name 
    data << "\n" 

    ActiveRecord::Base.connection.execute('UPDATE "users" SET "first_name" = \'Pengguna\' WHERE "users"."id" = 1') 
    data << User.find(1).first_name 
    data << "\n" 

    render plain: data 
    end 

# Browser 
Suwir Suwirr 
Suwir Suwirr 
関連する問題