Я не могу дать однозначного решения вашей проблемы, но надеюсь дать вам идеи, чтобы найти решение с желаемым уровнем производительности.
Нет. Подходит ли?
Во-первых, чтобы убедиться в этом, вы уверены, что ваш сценарий хорошо подходит для noSQL? CosmosDB светится, когда основной сценарий работает с точными данными (создание, выбор по идентификатору, обновление по идентификатору, удаление по идентификатору). Да, он определенно может выполнять ограниченные массовые операции и агрегации, но запрос миллионов требует его. С другой стороны, SQL предназначен для работы с большими наборами данных и действительно хорош для агрегирования.
Давайте предположим, что это проектное решение было тщательно взвешено, и noSQL лучше всего подходит по не упомянутым причинам.
Отладка для сложных данных
Не выполнять тесты производительности на локальном эмуляторе cosmosDB . Не. Это, очевидно, не реальная вещь (учитывая сеть, пропускную способность хранилища / время поиска, влияние системы), но только эмулирует это. Вы можете получить очень вводящие в заблуждение результаты. Раскрути реальный тестовый экземпляр .
Первым шагом к устранению проблем с производительностью запросов будет включить метрики выполнения запросов и посмотреть, на что эти 20 секунд действительно потрачены.
Кроме того, загрузка 38000 документов, скорее всего, никогда не поступит в виде одного пакета, проверьте, сколько фактически запросов продолжения выполняется на сервер cosmosDB.
Кроме того, запустите профилировщик и убедитесь, что узкое место действительно в CosmosDB. Если вы делаете много продолжительных вызовов И одновременно запрашиваете на многих устройствах, то это может часто происходить и в клиенте, и запросы летают в сети. Убедитесь, что вы не ограничены в клиенте (GC, стек Http, внутренняя блокировка, пулы соединений / потоков и т. Д.).
Data / Query design
Сокращение запрашиваемых данных
Если вы уже знаете deviceid
, то не запрашивайте его 38000+ раз - это просто балласт.
Уменьшить размер объекта модели
/ * еще около 200 пар ключ-значение * /
Это огромный объект. Я бы проверил, поможет ли разделение на более мелкие объекты cosmosDB тратить меньше времени на внутреннюю загрузку и обработку документов. Пример:
{
"p_A2": "93095",
"p_A3": "303883",
"battery" : {
"current": "4294967.10000",
"gauge": "38.27700",
"voltage": "13.59400"
}
...
}
Не уверен, как docDB хранит документы внутри себя (полный график против вложенных документов), но вы можете проверить, оказывает ли это влияние. Разница между 2 против 20 настолько велика, что намекает на то, что она может иметь значение.
Массив датчиков?
Запрос запрашивает только первый первый набор измерений. Нужен ли массив? Вы можете проверить, не влияет ли этот уровень на производительность.
Типы данных в модели
battery_current
и т. Д. Хранят числовые значения измерений датчика в виде длинных строк. Если они всегда являются числами, вы можете хранить их как числа и уменьшить размер документа на сервере и клиенте. На производительность клиента, вероятно, повлияло бы больше (строка = выделение кучи). Пример: "4294967.10000"
составляет 13 символов = 26B в клиенте (UTF-16).
Дизайн приложения
Тебе действительно нужны все эти 38000 или миллионы документов каждый раз? Подумайте, можете ли вы обойтись подмножеством ..
Если это для перемещения данных, то рассмотрите другие варианты (фабрика данных, изменение обработки подачи) для постепенной передачи измерений. Если это требуется приложению по запросу, рассмотрите возможность загрузки меньших таймфреймов (= меньше документов) и используйте кеширование для прошлых таймфреймов. Если вы можете, предварительно агрегируйте результаты перед кэшированием. Сенсорные данные прошлого, скорее всего, не изменятся.
Как всегда, рассмотрите ваше экономическое обоснование для ROI . Оптимизация всегда возможна, но иногда выгоднее скорректировать бизнес-требования, чем технические решения.