2017-05-15 2 views
0

私はリストを持っており、私はredisにキャッシュしたいと思います。私はハッシュを使ってそれを達成するために2つの方法を試みました。Redisのリストを保存

この最初のアプローチを検討してください。私は1つのハッシュを作成して、ハッシュ値などの項目を設定します。

// .. 

$apiArray = [..]; // array from parsing an api 

if(!$c->keys('lista')){ 
    foreach (json_decode($apiArray) as $item){ 
     $c->hset('lista', $item->id, serialize($item)); 
    } 
} 

foreach ($c->hgetall('lista') as $key){ 

    $item = unserialize($key); 

    echo '<p>'; 
    echo '<strong>id</strong>: '.$item->id.'<br>'; 
    echo '<strong>name</strong>: '.$item->name.'<br>'; 
    echo '<strong>email</strong>: '.$item->email.'<br>'; 
    echo '</p>'; 
} 

ループに10000個のアイテムの上に、それは0.5秒かかります。

これを検討してください。元の配列の各要素上の単一のハッシュ:

if(!$c->keys('lista:*')){ 
    foreach (json_decode($apiArray) as $item){ 
     $c->hset('lista:'.$item->id, 'element', serialize($item)); 
    } 
} 

foreach ($c->keys('lista:*') as $item) { 
    $item = unserialize($c->hget($item, 'element')); 

    echo '<p>'; 
    echo '<strong>id</strong>: '.$item->id.'<br>'; 
    echo '<strong>name</strong>: '.$item->name.'<br>'; 
    echo '<strong>email</strong>: '.$item->email.'<br>'; 
    echo '</p>'; 
} 

10000のレコードのループが3秒かかります。

これは私にとって非常に驚くべきことです.2番目はRedisの公式ドキュメントで扱われているアプローチであり、2番目のインデックス作成(zaddとsaddを使用)もサポートされているからです。

なぜ、最初のアプローチよりも遅いのですか?私は何かに間違っていますか?

ループ内のアイテムを取得するためにhgetall()メソッドを10000回呼び出す必要があるため、この問題が発生する可能性があります。これを同意できますか?

私は最初のアプローチを好むでしょうか?

はみんな

Mをいただきありがとうございます:)

答えて

2

コードの2番目のブロックが遅い理由は、それがループの反復ごとにhget呼び出しを行うということです。したがって、すべての反復により、Redisサーバーへのネットワークラウンドトリップが行われます。

対照的に、最初のコードブロックはループブロック内でネットワーク呼び出しを行いません。だから、はるかに速く走る。

+0

ありがとう、thatsは私に意味をなさない。しかし、今質問があります:ループでhget(またはスキャン)を呼び出すことを避けるためにwalkthroughtはありますか? – Mauro

+1

配列の要素ごとにハッシュを作成する代わりに、代わりに文字列値を使うようにデータを再構成できますか?次に、mgetを使用して複数の項目を取得し、いくつかの往復を保存することができます。 –

+0

またはパイプライニングを使用する –

1

リスト全体をキャッシュし、毎回大量に書き出して取り出すことに興味があるようです。その場合、できることは最大のパフォーマンスを得るためにJSONをレディスストリングに保存することです。

関連する問題