2016-10-22 9 views
0

Redisキャッシュを使用してページデータを格納しています。私はページにデータをページングする(遅延ロード)ことを示す必要があります。レコードの数が少なくなると、すべて正常に動作します。しかし、60kを超えるレコードをロードすると、非常に遅くなります。redisオブジェクトにページングとソートを直接適用します。

List<MyEntity> lstMyData = cont.Cache.GetObject<List<MyEntity>>("RedisKeyName") 
           .Where(x => x.Id == Id || x.Id == 0) 
           .OrderByDescending(x => x.TotalCount) 
           .Skip((page != 0 ? page - 1 : 0) * limit) 
           .Take(limit) 
           .ToList(); 

私はRedisのオブジェクトに照会し、直接ではなく、完全なリストを毎回フェッチする必要がありますが、適切な何かを見つけることができませんでした:私は、データをフェッチするには、次のコードを使用しています。助けてくれてありがとう。

+0

これらのレコードをRedisの 'LIST'に保存していますか? –

+0

いいえ、Redis Objectに格納します。 –

答えて

0

あなたのコードはあまりにも多くの作業をします。指定されたID(O(N))を持つすべてのレコードを取得するためにリストを反復し、結果のリストをソートし(O(Nlog(N)))、ページ処理を実行します(平均でO(N/2))。レコードが多すぎる場合は、非常に遅くなるはずです。データの格納方法を再設計する必要があります。

パフォーマンスを改善するためにRedis 'SORTED SETを使用してください。スコアとして記録のTotalCountと、SORTED SET内の指定されたIdのすべてのレコードを保存する

あなたがデータをフェッチする必要がある場合、あなたはO(log(N) + limit)にページ付け作業を行うZREVRANGEコマンドを使用することができ、Nは、与えられたIdのレコード数です。はるかに速くなければなりません。

// add records for Id1 
zadd Id1 TotalCount1 record1 
zadd Id1 TotalCount2 record2 
// ... 
zadd Id1 TotalCountN recordN 
// pagination for the given Id, page (beginning from 1) and limit 
zrevrange Id1 (page-1)*limit page*limit-1 
+0

あなたの答えをありがとう。私は並べ替えられたセットについて検索しました。ページングには適していますが、ソートされたセットを使用して複数のフィールドをソートすることはできますか? –

+1

@AhmedHassanスコアで並べ替えるので(実際には、すべての要素が同じスコア、つまり 'zrangebylex'を持っていれば、辞書順で並べ替えることもできます)、複数のフィールドを並べ替えたい場合は、トリック、すなわち複数のフィールドを持つスコアを生成する。たとえば、 'A'と' B'の両方をソートし、 'B'が' [0 - 9] 'の範囲にあると仮定すると、' A * 10 + B'のようなスコアを生成することができます。このようなスコアを生成できない場合、複数のフィールドをソートすることはできません。 –

関連する問題