我正在编写一个过滤查询来查找已知日期时间较新的行。我认为此查询将运行一次并完成并返回找到的记录,但此查询未完成。我找不到有关行为的相关文档。
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()
);
}
你看到的行为是正确的。基本上你所看到的是Partition Scan
。关于表存储的一些事情:
PartitionKey
和RowKey
属性被编入索引。你可以在这里阅读更多相关信息: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。