Самый быстрый способ запроса последних элементов в таблице Azure? - PullRequest
13 голосов
/ 08 сентября 2011

У меня есть таблица Azure, где клиенты публикуют сообщения, в одной таблице могут быть миллионы сообщений.Я хочу найти самый быстрый способ отправки сообщений за последние 10 минут (именно так часто я обновляю веб-страницу).Поскольку индексируется только ключ раздела, я решил использовать дату и время, когда сообщение было опубликовано, в качестве ключа раздела, например строку в формате даты ISO8601, например «2009-06-15T13: 45: 30.0900000»

Пример псевдокода:

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
   )

будет ли это хорошо воспринято индексом?Или это приведет к полному сканированию таблицы?У кого-нибудь есть идея получше?Я знаю, что на каждом элементе таблицы есть временная метка, но она не индексируется, поэтому она будет слишком медленной для моей цели.

Ответы [ 4 ]

5 голосов
/ 08 сентября 2011

Я думаю, у вас есть правильная основная идея.Разработанный вами запрос должен быть настолько эффективным, насколько вы можете надеяться.Но есть некоторые улучшения, которые я мог бы предложить.

Вместо использования DateTime.Now используйте Date.UtcNow.Насколько я понимаю, экземпляры в любом случае настроены на использование времени Utc, но это просто гарантирует, что вы сравниваете яблоки с яблоками, и вы можете надежно преобразовать время обратно в любой часовой пояс, который вы хотите при их отображении.* Вместо сохранения времени как .ToString("o"), превращающего время в тики и сохраняющего его, вы получите меньше проблем с форматированием (иногда вы получите спецификацию часового пояса в конце, иногда нет).Также, если вы всегда хотите видеть эти сообщения отсортированными от самых последних к старым, вы можете вычесть количество тиков из максимального количества тиков, например:

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

Также было бы неплохо указать ключ строки,Хотя маловероятно, что два сообщения будут опубликованы в одно и то же время, это не невозможно.Если у вас нет очевидного ключа строки, просто установите его как Guid.

4 голосов
/ 14 февраля 2012

Первичный ключ для таблицы - это комбинация PartitionKey и RowKey (которая формирует кластеризованный индекс).

В вашем случае просто используйте RowKey вместо ParitionKey (предоставьте для этого постоянное значение).

Вы также можете следовать подходу диагностики, например, каждые десять минут создавать новый ключ раздела.Но этот подход в основном для таких требований, как архивирование / очистка и т. Д.,

3 голосов
/ 08 сентября 2011

Я бы предложил сделать что-то похожее на то, что делает API диагностики с WADPerformanceCountersTable. Там PartitionKey группирует несколько временных меток в один элемент. То есть: он округляет все метки времени в ближайшие несколько минут (скажем, ближайшие 5 минут). Таким образом, у вас не будет ограниченного количества ключей разделов, и вы все равно сможете выполнять запросы с ними на расстоянии.

Так, например, у вас может быть PartitionKey, который сопоставляется с каждой отметкой времени, округленной до 00:00, 00:05, 00:10, 00:15 и т. Д., А затем преобразованной в тики

0 голосов
/ 30 июня 2016
  • Насколько я понимаю, использование ключа раздела с точным равным "=" будет намного быстрее, чем меньше, чем использование "<" или "больше, чем">.
  • Также приложите больше усилий, если мы сможем получить уникальную комбинацию ключа раздела и ключа строки для вашего состояния.
  • Также убедитесь, что вы используете меньше уникальных комбинаций значений ключей разделов, чтобы избежать большего количества разделов.
...