天蓝色表存储:实体过滤器查询不会终止

时间:2019-03-18 05:59:50

标签: azure azure-table-storage

我正在编写一个过滤器查询,以查找来自已知日期时间的较新行。我认为此查询将运行一次并完成并返回找到的记录,但是此查询未完成。我找不到有关该行为的相关文档。

        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 :(得分:0)

您看到的行为是正确的。基本上,您会看到Partition Scan。有关表存储的一些事项:

  • 仅索引PartitionKeyRowKey属性。
  • 对表存储的查询在单个请求中最多只能返回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