Запрос Azure DocumentDB по идентификатору очень медленный
Я получил коллекцию 16GB с 2 разделами. Когда я запрашиваю документ по его идентификатору, он очень медленный. Но запросы по индексированному полю быстрые. Оба являются запросами с несколькими разделами, и если я передаю ключ раздела вместе с запросом, это быстро, но ключ раздела не всегда доступен для моего запроса. Получили аналогичные результаты, используя.NET SDK и Document Explorer Query в Azure Portal.
В коллекции есть пользовательская политика индексирования, но, насколько я знаю, индексировать не нужно Id
или это может быть даже невозможно.
Вот мои запросы и соответствующие сборы за запросы.
SELECT * FROM c where c.id = 'unique-id-123'
-- Request Charge: 344940.79 RUs, Document Count: 1
SELECT * FROM c WHERE c.otherId = 'NOT-so-uniqueId-123'
-- Request Charge: 5.08 RUs, Document Count: 3
Как вы знаете, идентификатор уникален, поэтому запрос возвращает 1 документ, а второй запрос фильтруется otherId
который не так уникален и возвращает 3 документа. Также обратите внимание на безумно высокое потребление RU с первым запросом.
Так почему 2-й запрос быстрее, чем по Id?
Обновить:
Вот собранные метрики для вышеупомянутых запросов.
Запрос по идентификатору:
Read 1 records in 1497 ms, 339173.109 RU, Size: 6873022 KB
QueryPreparationTime(ms): CompileTime = 2, LogicalBuildTime = 0,
PhysicalPlanBuildTime = 0, OptimizationTime = 0
QueryEngineTime(ms): DocumentLoadTime = 1126, IndexLookupTime = 0,
RuntimeExecutionTimes = 356, WriteOutputTime = 0
Запрос по индексированному полю:
Read 4 records in 2 ms, 7.56 RU, Size: 9 KB
QueryPreparationTime(ms): CompileTime = 0, LogicalBuildTime = 0,
PhysicalPlanBuildTime = 0, OptimizationTime = 0
QueryEngineTime(ms): DocumentLoadTime = 0, IndexLookupTime = 1,
RuntimeExecutionTimes = 0, WriteOutputTime = 0
Это доказывает, что запрос по идентификатору выполняет сканирование таблицы, поскольку большая часть времени была DocumentLoadTime
и не имеет значения для IndexLookupTime
,
Но я подумал, что Id должен быть первичным ключом и индексироваться по умолчанию согласно этому ответу @ andrew-liu.
2 ответа
Служба поддержки Microsoft ответила, и они решили проблему. Они добавили IndexVersion
2 для коллекции. К сожалению, он еще не доступен на портале, и вновь созданные учетные записи / коллекции по-прежнему не используют новую версию. Вам нужно будет связаться со службой поддержки Microsoft, чтобы внести изменения в свои учетные записи.
Вот новые результаты из коллекции с индексом версии 2, и есть значительное улучшение.
SELECT * FROM c where c.id = 'uniqueValue'
-- Index Version 1: Request Charge: 344,940.79 RUs
-- Index Version 2: Request Charge: 3.31 RUs
SELECT * FROM c WHERE c.indexedField = 'value' AND c.id = 'uniqueValue'
-- Index Version 1: Request Charge: 150,666.22 RUs
-- Index Version 2: Request Charge: 5.65 RUs
Поле "Id" уникально только в ключе раздела. Это, вероятно, сторона того, почему ваш запрос стоит так дорого, если вы настроили индексацию вручную.
К сожалению, невозможно контролировать индексацию поля id. Вы можете попробовать проверить, улучшается ли производительность запроса, если вы все индексируете. Было бы интересно, если бы что-то изменилось для ваших данных, хотя ничего не изменилось для моего небольшого набора выборок.
The specified path '/id/?' could not be accepted because it overrides system property 'id'.
По моему опыту, запросы DocumentDB на самом деле могут стать дешевле, если у вас есть пара результатов в каждом разделе. Они могут быть очень дорогостоящими, если в разделе нет результатов. Попробуйте поместить второй документ с тем же идентификатором в другой раздел и посмотрите, как меняется производительность. Без перекрестного запроса ответы всегда бывают чрезвычайно быстрыми при запросах с индексированным полем, независимо от количества результатов.
Я никогда не исследовал больше, так как это никогда не беспокоило меня в реальных случаях использования. Также может быть, что количество элементов на раздел не оказывает реального влияния, и мои данные несут ответственность.