хранение таблицы Azure: запрос фильтра сущностей не прекращается - PullRequest
0 голосов
/ 18 марта 2019

Я пишу запрос фильтра, чтобы найти строки новее из известного времени.Я думал, что этот запрос будет выполнен один раз, завершит и вернет найденные записи, но этот запрос не будет завершен.Я не смог найти соответствующую документацию по поведению.

        TableQuery<Reading> partitionQuery = TableQuery.from(Reading.class);
        partitionQuery.setFilterString("PartitionKey eq 'partition1' and Timestamp gt datetime'2019-03-18T05:34:56+00:00'");
        partitionQuery.setTakeCount(100);


        Iterable<Reading> readingIterable = cloudTable.execute(partitionQuery);
        for (Reading entity : readingIterable) {
            System.out.println(entity.getPartitionKey() +
                    " " + entity.getRowKey() +
                    " " + entity.getTimestamp() 
            );
        }

1 Ответ

0 голосов
/ 18 марта 2019

Поведение, которое вы видите, правильное. По сути, вы видите Partition Scan. Несколько вещей, когда дело доходит до хранения таблицы:

  • Индексируются только атрибуты PartitionKey и RowKey.
  • Запрос к хранилищу таблиц возвращает максимум 1000 объектов в одном запросе (он также не может возвращать никаких объектов).
  • Каждому запросу назначается максимум 5 секунд для выполнения. Если совпадающие данные найдены, они возвращаются. Если доступно больше данных, возвращается токен продолжения, и вы должны использовать этот токен вместе с тем же запросом, чтобы получить следующий набор данных.

Подробнее об этом можно прочитать здесь: https://docs.microsoft.com/en-us/rest/api/storageservices/query-timeout-and-pagination.

Теперь подходит к вашей ситуации. Вы упомянули, что каждую секунду новая запись вставляется в один и тот же раздел. Поскольку вы запрашиваете PartitionKey (индексированный атрибут) и Timestamp (неиндексированный атрибут), запрос выполняется начиная с вершины раздела и пытаясь найти подходящие объекты. Поскольку последние записи добавляются в конец раздела, метод execute выполняет внутренний цикл для поиска подходящих объектов, и это может занять много времени в зависимости от количества объектов в таблице.

Чтобы получить последние записи, я думаю, вам нужно переосмыслить способ хранения данных. Одним из решений будет использование даты / времени, когда запись создается как PartitionKey. Для добавления (вместо добавления) можно использовать механизм Reverse Ticks ((DateTime.MaxValue.Ticks - DateTime.UtcNow.Ticks).ToString("d19")). Это были новые сущности, которые всегда добавляются в верхнюю часть таблицы.

Вы также можете прочитать это руководство: https://docs.microsoft.com/en-us/azure/cosmos-db/table-storage-design-guide.

...