Пейджинговая производительность Cosmos DB с OFFSET и LIMIT - PullRequest
1 голос
/ 08 ноября 2019

Я создаю API на основе Cosmos DB и ASP.NET Core 3.0. Использование предварительного просмотра Cosmos DB 4.0 1 .NET Core SDK. Я реализовал пейджинг с использованием предложений OFFSET и LIMIT. Я вижу, как значительно увеличивается плата за добавление RU, по мере увеличения количества страниц. Пример для страницы размером 100 элементов:

Page 1: 9.78 RU
Page 10: 37.28 RU
Page 100: 312.22 RU
Page 500: 358.68 RU

Запросы просто:

ВЫБРАТЬ * из c СМЕЩЕНИЕ [размер страницы] ПРЕДЕЛ [размер]

утраЯ делаю что-то не так, или это ожидается? Требуется ли для OFFSET сканирование всего логического раздела? Я запрашиваю один ключ раздела с примерно 10000 элементами в разделе. Кажется, чем больше элементов в разделе, тем хуже производительность. (См. Также комментарий "Russ" в uservoice для этой функции).

Есть ли лучший способ реализовать эффективный пейджинг через весь раздел?

Редактировать 1: Я также замечаю, что выполнение запросов в эмуляторе космоса также замедляет процесс ожидания при выполнении OFFSET / LIMIT враздел с 10 000 элементов.

Редактировать 2: Вот мой код хранилища для запроса. По сути, это обертка метода Container.GetItemQueryStreamIterator () и извлечение RU при обработке IAsyncEnumerable. Сам запрос представляет собой приведенную выше строку SQL, здесь нет LINQ или другой загадки.

public async Task<RepositoryPageResult<T>> GetPageAsync(int? page, int? pageSize, EntityFilters filters){

// Enforce default page and size if null
int validatedPage = GetValidatedPageNumber(page);
int validatedPageSize = GetValidatedPageSize(pageSize);

IAsyncEnumerable<Response> responseSet = cosmosService.Container.GetItemQueryStreamIterator(
    BuildQuery(validatedPage, validatedPageSize, filters),
    requestOptions: new QueryRequestOptions()
    {
        PartitionKey = new PartitionKey(ResolvePartitionKey())
    });

var pageResult = new RepositoryPageResult<T>(validatedPage, validatedPageSize);
await foreach (Response response in responseSet)
{
    LogResponse(response, COSMOS_REQUEST_TYPE_QUERY_ITEMS); // Read RU charge
    if (response.Status == STATUS_OK && response.ContentStream != null)
    {
        CosmosItemStreamQueryResultSet<T> responseContent = await response.ContentStream.FromJsonStreamAsync<CosmosItemStreamQueryResultSet<T>>();
        pageResult.Entities.AddRange(responseContent.Documents);
        foreach (var item in responseContent.Documents)
        {
            cache.Set(item.Id, item); // Add each item to cache
        }
    }
    else
    {
        // Unexpected status. Abort processing.
        return new RepositoryPageResult<T>(false, response.Status, message: "Unexpected response received while processing query response.");
    }
}

pageResult.Succeeded = true;
pageResult.StatusCode = STATUS_OK;
return pageResult;

}

Редактировать 3:

Запуск того же необработанного SQL из cosmos.azure.com, я заметил в статистике запросов:

OFFSET 0 LIMIT 100: Output document count = 100, Output document size = 44 KB
OFFSET 9900 LIMIT 100: Output document count = 10000, Output document size = 4.4 MB

И действительно, проверка вкладки сети в браузере показывает 100 отдельных HTTP-запросов, каждый из которых получает 100 документов! Таким образом, OFFSET в настоящее время, по-видимому, находится не в базе данных, а на клиенте, который получает ВСЕ, прежде чем выбросить данные за первые 99 запросов. Это не может быть предполагаемый дизайн? Разве запрос не должен указывать базе данных возвращать всего 100 элементов в одном ответе, а не все 10000, чтобы клиент мог выбросить 9900?

1 Ответ

0 голосов
/ 09 ноября 2019

На основании кода это будет означать, что клиент пропускает документы и, следовательно, увеличивает количество RU.

Я тестировал тот же сценарий в браузере (cosmos.azure.com, использует JS SDK) и поведение такое же, как и смещения, RU увеличивается.

Paging in cosmos.azure.com

Paging in cosmos.azure.com increasing OFFSET

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...