DBICでの簡単キャッシング
DBICで簡単にお金が借りることができます(ちが
まあ、面白くないのでやめておきますが、DBICは
かなりパフォーマンスに気を使った設計なのは周知の事実なのでつが、
キャッシュを使うことでよりパフォーマンス向上が図れます。
例えば
my $itr = $self->model('Member')->search({},{}); while (my $member = $itr->next) { warn $member->id; } $itr->reset; while (my $member = $itr->next) { warn $member->id; }
こんな感じの処理があったとします。
Memberテーブルを二度処理するみたいな。
ちなみに同じオブジェクトを使う時は
$itr->reset;
こうしてやればイテレータがリセットされます。
この場合、2個のwhileのところでそれぞれSQLが実行されます。
こんな感じ
Executing : SELECT me.id, me.rid, me.name, me.created_on, me.timestamp FROM member me ORDER BY me.id DESC : -->Query Time: 0.001609. -->ALL Query Time: 0.001609 --------------------------------------------------------------------------------- 8 at ./TestDBIC/Script/Test.pm line 11. 7 at ./TestDBIC/Script/Test.pm line 11. Executing : SELECT me.id, me.rid, me.name, me.created_on, me.timestamp FROM member me ORDER BY me.id DESC : -->Query Time: 0.000998. -->ALL Query Time: 0.002607 --------------------------------------------------------------------------------- 8 at ./TestDBIC/Script/Test.pm line 15. 7 at ./TestDBIC/Script/Test.pm line 15.
しかし、
my $itr = $self->model('Member')->search({},{cache => 1}); while (my $member = $itr->next) { warn $member->id; } $itr->reset; while (my $member = $itr->next) { warn $member->id; }
こんな感じでcacheを設定してやれば
1個目のwhileでSQLが実行され、
2個目のwhileでは1個目の結果が再利用されます。
こんな感じ
Executing : SELECT me.id, me.rid, me.name, me.created_on, me.timestamp FROM member me ORDER BY me.id DESC : -->Query Time: 0.001563. -->ALL Query Time: 0.001563 --------------------------------------------------------------------------------- 8 at ./TestDBIC/Script/Test.pm line 11. 7 at ./TestDBIC/Script/Test.pm line 11. 8 at ./TestDBIC/Script/Test.pm line 15. 7 at ./TestDBIC/Script/Test.pm line 15.
ただ、インスタンスを捨てるとダメ。当然だけど。
まあ、普通にCache::Memcachedを使ってキャッシュするのであれば、
sub cache { my $self = shift; $self->{__cache} ||= Cache::Memcached->new({ servers => [ $self->config->cache_servers ], }); } sub run { my $self = shift; my $results = $self->cache->get('test_cache'); unless ( $results ) { $results = [ $self->model('Member')->search({},{}) ]; $self->cache->set('test_cache', $results, 60*10); } for my $member (@{$results}) { warn $member->id; } }
こんな感じになるかな。でも微妙っす。