2015-09-17 2 views
0

У меня есть таблица Azure, которая содержит более миллиона записей, и я пытаюсь сделать около 300 000 запросов программно в C#, чтобы перенести некоторые данные в другую систему. В настоящее время я делаю следующее, как я прочитал файл, который имеет перегородку и рядные ключи:Лучший способ сделать большое количество запросов в Azure Table?

while (!reader.EndOfStream) 
{ 
    // parse the reader to get partition and row keys 
    string currentQuery = TableQuery.CombineFilters(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, partKey), TableOperators.And, TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.Equal, rowKey)); 
    TableQuery<MyEntity> query = new TableQuery<MyEntity>().Where(currentQuery); 

    foreach (MyEntity entity in table.ExecuteQuery(query)) 
    { 
     Console.WriteLine(entity.PartitionKey + ", " + entity.RowKey + ", " + entity.Timestamp.DateTime); 
    } 

    Thread.Sleep(25); 
} 

Это занимает очень много времени, чтобы завершить (5 + часов). Запросы берут в среднем около 200 миллисекунд из того, что я вижу. Я новичок в Azure, поэтому считаю, что я делаю что-то неправильно. Как я могу улучшить его?

+0

Предложение: экспортируйте базу данных из Azure и поместите ее на локальный SQL-сервер. Затем запустите свой код и посмотрите, быстрее ли он. – mrunion

+1

@mrunion - Это предложение действительно не связано с ответом на вопрос. –

ответ

2

Несколько вещей:

  1. Не знаю, почему у вас есть вызов сна в вашем цикле. Если вы не дросселируете (хранилище поддерживает 20 000 транзакций в секунду), вам это не нужно.
  2. С заданным ключом раздела и ключом строки вы получите ровно один возвращенный объект (поскольку комбинация pk + rk уникальна). Не нужно перебирать результаты. Вы либо получите нуль, либо один.
  3. Вы используете однопоточный подход, поэтому маловероятно, что вы сможете очень сильно повысить ставки транзакций хранения. Рассмотрим распараллеливание результатов поиска.
  4. Я предполагаю, что вы не звоните Console.Writeline() в свое приложение. Если это так, это также замедлит вас.
  5. Рассмотрите возможность отключения алгоритма Нагле через ServicePointManager.UseNagleAlgorithm = false;. В противном случае индивидуальные низкоуровневые вызовы на хранение могут быть буферизованы до 500 мс, чтобы более плотно упаковать пакеты tcp. Это будет важно, если вы тратите циклы обработки содержимого, которое вы читаете.
+0

Спасибо за ваш ответ. Что касается распараллеливания моего кода, какой был бы лучший способ для этого? Я попытался использовать threadpools, но мое общее время выполнения не изменилось. –

 Смежные вопросы

  • Нет связанных вопросов^_^