azure表存储:实体过滤器查询不终止

问题描述 投票:0回答:1

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

        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() 
            );
        }

azure azure-table-storage
1个回答
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

© www.soinside.com 2019 - 2024. All rights reserved.