有哪些方法可以优化从Azure表存储到.NET应用程序的单个分区中检索大量实体(~250K)?
答案 0 :(得分:3)
据我所知,有两种方法可以优化从Azure表存储到.NET应用程序的单个分区中检索大量实体。
1.如果您不需要获取实体的所有属性,我建议您使用服务器端投影。
单个实体最多可以包含255个属性,最大可达1 MB。查询表并检索实体时,您可能不需要所有属性,并且可以避免不必要地传输数据(以帮助减少延迟和成本)。您可以使用服务器端投影来仅传输所需的属性。
自:Azure Storage Table Design Guide: Designing Scalable and Performant Tables(Server-side projection)
更多细节,您可以参考以下代码:
string filter = TableQuery.GenerateFilterCondition(
"PartitionKey", QueryComparisons.Equal, "Sales");
List<string> columns = new List<string>() { "Email" };
TableQuery<EmployeeEntity> employeeQuery =
new TableQuery<EmployeeEntity>().Where(filter).Select(columns);
var entities = employeeTable.ExecuteQuery(employeeQuery);
foreach (var e in entities)
{
Console.WriteLine("RowKey: {0}, EmployeeEmail: {1}", e.RowKey, e.Email);
}
2.如果您只想显示表格的消息,则无需同时获取所有实体。 你可以得到部分结果。 如果要获取其他结果,可以使用延续令牌。 这将改善表查询性能。
针对表服务的查询一次最多可返回1,000个实体,并且最多可执行五秒。如果结果集包含超过1,000个实体,如果查询未在五秒内完成,或者查询超过分区边界,则表服务将返回一个延续令牌,以使客户端应用程序能够请求下一组实体。有关延续令牌如何工作的详细信息,请参阅查询超时和分页。
通过明确使用延续令牌,您可以控制应用程序何时检索下一段数据。
更多细节,您可以参考以下代码:
string filter = TableQuery.GenerateFilterCondition(
"PartitionKey", QueryComparisons.Equal, "Sales");
TableQuery<EmployeeEntity> employeeQuery =
new TableQuery<EmployeeEntity>().Where(filter);
TableContinuationToken continuationToken = null;
do
{
var employees = employeeTable.ExecuteQuerySegmented(
employeeQuery, continuationToken);
foreach (var emp in employees)
{
...
}
continuationToken = employees.ContinuationToken;
} while (continuationToken != null);
此外,我建议你可以关注表分区可扩展性目标。
单个表分区的目标吞吐量(1 KB实体)每秒最多2000个实体
如果达到此分区的可伸缩性目标,存储服务将会限制。