2011-09-07 7 views
13

顧客がメッセージを投稿するAzureテーブルがあり、1つのテーブルに数百万のメッセージが存在する可能性があります。私は過去10分間にメッセージを投稿する最速の方法を見つけたいと思っています(これは、Webページを更新する頻度です)。パーティションキーのみが索引付けされているので、私は日付が&の日付を使用するというアイデアを持っていました。たとえば、「2009-06-15T13:45:30.0900000」のようなISO8601日付書式の文字列がパーティションキーとしてメッセージとして投稿されました。Azureテーブルの最新のアイテムを検索する最速の方法は?

例の擬似コード:

var message = "Hello word!"; 
var messagePartitionKey = DateTime.Now.ToString("o"); 
var messageEntity = new MessageEntity(messagePartitionKey, message); 
dataSource.Insert(messageEntity); 

、その後、(再びテストされていない疑似コード)は、このような最後の10分以内に投稿されたメッセージを照会:

// Get the date and time 10 minutes ago 
var tenMinutesAgo = DateTime.Now.Subtract(new TimeSpan(0, 10, 0)).ToString("o"); 

// Query for the latest messages 
var latestMessages = (from t in 
    context.Messages 
    where t.PartitionKey.CompareTo(tenMinutesAgo) <= 0 
    select t 
    ) 

しかし、これは、によっても取られますインデックス?それとも、それは完全なテーブルスキャンを引き起こすでしょうか?誰もがこれを行うより良いアイデアを持っていますか?私は、各テーブル項目にタイムスタンプがあることを知っていますが、索引付けされていないので、自分の目的には遅すぎます。

+0

サイドローブとして、より一般的なものをパーティションキーとして使用することをお勧めします。あなたの投稿が所属する場所など。 http://msdn.microsoft.com/en-us/library/windowsazure/hh508997.aspxを見てください –

+0

同じマシンが挿入とクエリの両方を実行していますか?そうでない場合は、クライアント間のクロックスキューを考慮する必要があります。 –

答えて

5

あなたは正しい基本理念を持っていると思います。設計したクエリは、あなたが望むほど効率的でなければなりません。しかし、私が提供できるいくつかの改善があります。

DateTime.Nowを使用するのではなく、Date.UtcNowを使用してください。あなたがリンゴとリンゴを比較していることを確かめ、それらを表示するときにあなたが望むどんなタイムゾーンにも信頼できる時間を戻すことができます。

時刻を.ToString("o")として保存するのではなく、時間を目盛りにして保存することで、フォーマットの問題が少なくなります(最終的にタイムゾーンの指定を取得することもあります)。また、これらのメッセージが最新のものから古いものにソートされていることを常に確認したい場合は、ダニの最大数からダニの数を減算することができます。

var messagePartitionKey = (DateTime.MaxValue.Ticks - _contactDate.Ticks).ToString("d19"); 

また、行キーを指定することをお勧めします。 2つのメッセージが全く同じ時間に投稿されることはほとんどありませんが、不可能ではありません。明らかな行キーがない場合は、それを単にGuidに設定してください。

+0

ティックはレコードごとにユニークで、各パーティションキーごとに単一のパーティションを作成します。私はダニを取ることがベストアイデアだとは思わない。 – Kurkula

+1

はい、これは行ごとにパーティションを作成しますが、このような状況ではパーティションを作成する上で不利益はありません。 – knightpfhor

+0

複数のパーティションを作成すると、パフォーマンスが低下します。 – Kurkula

3

私は、Diagnostics APIがWADPerformanceCountersTableでやっていることに似た何かをすることをお勧めします。 PartitionKeyは、単一の項目に複数のタイムスタンプをグループ化します。つまり、すべてのタイムスタンプを最も近い数分(たとえば、最も近い5分)に丸めます。この方法では、限られた量のパーティションキーを持っていなくても、それらに対して依然として遠隔クエリを実行できます。

したがって、たとえば、あなたがなど、午後12時15分、午前0時10分、午後12時05、午後12時00分に丸められ、各タイムスタンプにマップのPartitionKeyを持つことができます。..して、ダニ

+0

非常に良い選択肢のようですが、私のシナリオでは、ページは多くのクライアントによって異なる間隔で更新されます。私は要求がいつ来るかわからず、クライアントに同じか少なすぎるメッセージを送り返す危険性がありません。 –

+0

私はこの考えが好きです。 – Roboblob

4
に変換しました

テーブルの主キーは、PartitionKeyとRowKey(クラスタ化インデックスを形成する)の組み合わせです。

あなたの場合、ParitionKeyの代わりにRowKeyを使用してください(これには一定の値を指定してください)。

また、10分ごとに新しいパーティションキーを作成するような診断方法に従うこともできます。しかし、このアプローチは主にArchieving/Purgingなどの要件に対応しています。、

0
  • 正確に等しい "="のパーティションキーを使用していると私の理解では、 "<"または "より大きい"を使用するよりもずっと速くなります。
  • 条件に合ったパーティションキーと行キーを組み合わせることができれば、もっと努力してください。
  • また、より多くのパーティションを避けるために、パーティションキー値の一意の組み合わせが少なくてすむようにしてください。
関連する問題