У нас есть огромный контейнер CosmosDB с миллиардами строк и почти 300 столбцами. Данные секционируются и моделируются так, как мы запрашиваем их большую часть времени.
Например: пользовательская таблица разделена по идентификатору пользователя, поэтому нижеприведенный запрос работает нормально.
Select * from User where userId = "user01234"
Но в некоторых случаях нам нужно запросить данные по-другому, которые требуют сортировки, а затем запроса.
Например: получить данные из пользовательской таблицы, используя сообщение пользователя и дату публикации.
Select * from user where userPostId = "P01234" orderBy date limit 100
Этот запрос занимает много времени из-за размера данных, а данные не разделены на основе запроса2 (сообщение пользователя).
Мой вопрос: как мы можем сделать query2 и другие подобные запросы быстрее, если данные не разделены соответствующим образом.
Вариант 1: «Создать отдельную коллекцию, разделенную согласно Query2» — Это сделает запрос быстрее, но для любого нового запроса мы в конечном итоге создадим новую коллекцию, которая дублирует миллиарды записей. [Дорогой вариант]
Вариант 2: «Создать эластичный поиск поверх БД?» Это трудоемкий вариант, и он может быть излишним для этой проблемы с медленным запросом.
Есть ли другой вариант, который можно использовать? Дайте мне знать, что вы думаете.
Заранее спасибо!






Оба варианта дорогие. Ключ в том, чтобы решить, что дешевле, включая выполнение запроса между разделами. Это потребует от вас затрат на каждый из этих вариантов.
Для запроса между разделами зафиксируйте стоимость RU в объекте ответа, чтобы вы знали ее стоимость.
Для фида изменений это будет иметь первоначальную стоимость, поскольку вы запускаете ее для существующей коллекции, но останется ли эта стоимость высокой, зависит от того, сколько данных вставляется или обновляется каждый месяц. Расчет стоимости заполнения вашей второй коллекции потребует некоторой работы. Вы можете начать с измерения заряда RU в объекте ответа при выполнении вставки, а затем умножить на количество строк. Расчет необходимой пропускной способности будет зависеть от того, насколько быстро вы хотите заполнить вторую коллекцию. Это также зависит от того, сколько вычислений и сколько экземпляров вы используете для чтения и записи данных во вторую коллекцию.
Как только вторая коллекция будет заполнена, фид изменений будет стоить 2 ЕЗ/с для опроса изменений (кстати, это настраивается) и 1 ЕЗ/с для чтения каждого нового элемента. Стоимость вставки данных во вторую коллекцию стоит столько же, сколько вы оценивали ранее.
Если этот второй запрос выполняется не так часто и ваши данные меняются не так сильно, то фид изменений может сэкономить вам деньги. Если вы часто выполняете этот запрос и ваши данные также часто меняются, фид изменений может сэкономить вам деньги.
Что касается эластичного поиска или поиска Azure, я обычно считаю, что это может быть дороже, чем сохранение запроса между разделами или веб-канала изменений. Особенно, если вы делаете это, чтобы просто ответить на второй запрос. Как правило, это лучший вариант, когда вам нужны настоящие возможности текстовых запросов.
Третий вариант, который вы можете изучить, — использовать Azure Synapse Link, а затем выполнить оба запроса с помощью SQL Serverless или Spark.
Некоторые другие наблюдения.
Если вам не нужны все 300 свойств в этих запросах, вы можете рассмотреть возможность разделения этих элементов на отдельные документы и хранения в виде отдельных строк. Особенно, если у вас очень асимметричные шаблоны обновления, когда часто обновляется лишь небольшое количество свойств. Это сэкономит вам кучу денег на обновлениях, потому что чем меньше элемент, который вы обновляете, тем дешевле (и быстрее) он будет.
Еще я бы посоветовал посмотреть на политику индексирования и исключить каждое свойство, которое не используется в предложении where для ваших запросов, и включить свойства, которые используются. Это сильно повлияет на потребление RU для вставок. Также взгляните на составной индекс для вашего свойства даты, так как это оказывает существенное влияние на запросы, которые используют порядок.
Трудно сказать, является ли поиск лучшим вариантом. Если ваши другие запросы выглядят как ваш второй, я думаю, что Synapse Link может быть лучшим вариантом в долгосрочной перспективе.
Большое спасибо, Марк, за подробное объяснение. Я склонялся к варианту эластичного поиска, потому что, как и в случае с query2, у нас может быть больше запросов в будущем, и если таких запросов будет 5+, то 5 коллекций похожих данных с разными ключами раздела звучат дороже, чем эластичный поиск, что вы думаете? Что касается Azure Synapse Link и spark, я рассмотрю это. Еще раз спасибо!