1

GET /Product()?$filter=((PartitionKey%20eq%20'lIkfA81JpTmv')%20and%20(RowKey%20eq%20'')) %20or%20((PartitionKey%20eq%20'lIGcEmrr7hWz')%20and%20(RowKey%20eq%20'')) %20or%20((PartitionKey%20eq%20'lIAoy6PqeMVn')%20and%20(RowKey%20eq%20'')) %20or%20((PartitionKey%20eq%20'lIjETAtuhYGM')%20and%20(RowKey%20eq%20'')) %20or%20((PartitionKey%20eq%20'lIHa0znP5qAk')%20and%20(RowKey%20eq%20'')) %20or%20((PartitionKey%20eq%20'lIOCaSXg9YE7')%20and%20(RowKey%20eq%20'')) %20or%20((PartitionKey%20eq%20'lInRozGrMa7T')%20and%20(RowKey%20eq%20'')) %20or%20((PartitionKey%20eq%20'lILEwwPPcBfe')%20and%20(RowKey%20eq%20'')) %20or%20((PartitionKey%20eq%20'lJ14qZv1KFn4')%20and%20(RowKey%20eq%20''))% 20or%20((PartitionKey%20eq%20'lIIohzupFLcV')%20and%20(RowKey%20eq%20'')).....

对已知 PartitionKey 和 RowKey 的列表 (50) 的 Azure 表存储非常标准的查询。从服务器开始第一口需要 5 秒。有没有办法加快速度?

4

2 回答 2

2

“或”查询并未按照您期望的方式进行优化。像这样的查询会导致全表扫描。正如 Gaurav 建议的那样,您确实需要将这些作为单独的查询(并行)进行,以获得快速的响应时间。

我也完全不同意 Astaykov 的说法,即您不应该费心优化,因为您的性能在 SLA 范围内。性能不是随机的,SLA 通常是一个上限。请花时间优化对性能敏感的查询。您应该能够轻松地在亚秒级时间内始终如一地进行这种查找。

编辑:

不确定您使用的是哪种语言,但这里有一个快速的 Node.js 测试,从我家开始似乎通常需要 1 到 1.2 秒,但偶尔会接近 1.5:

function timeParallelQueries(account, key) {
    var azure = require('azure'),
        Q = require('q'),
        _ = require('underscore');

    var tables = azure.createTableService(account, key);

    function convertToString(n) { return n + ''; }

    var start = null;

    Q.ncall(tables.createTableIfNotExists, tables, 'test')
    .then(function () {
        return Q.all(_.map(_.map(_.range(50), convertToString), function(key) {
            return Q.ncall(tables.insertOrReplaceEntity, tables, 'test', {PartitionKey: key, RowKey: key});
        }));
    })
    .then(function () {
        start = new Date();
        return Q.all(_.map(_.map(_.range(50), convertToString), function (key) {
            return Q.ncall(tables.queryEntity, tables, 'test', key, key);
        }));
    })
    .then(console.log)
    .then(function (results) {
        console.log('Took ' + (new Date() - start) + 'ms.');
    });
}
于 2012-08-15T16:51:16.670 回答
1

除了您正在查询“已知”的 PK 和 RK 之外,您还为其中的许多提供了 OR。考虑到不同分区分布在不同物理服务器上的机会非常高,我对结果并不感到惊讶。

同样根据Storage SLA,一个表操作:

必须在 10 秒内完成处理或返回继续

单个实体(即单对 PK & RK)进行操作时:

必须在 2 秒内完成处理

所以 5 秒是平均水平,并且在 SLA 范围内。即使您以某种方式加快查询速度,它也不可靠,因为您的查询的 SLA 是“在 10 秒内”。因此,您在优化查询方面所做的所有努力都可能被浪费,因为这是一个可变时间,取决于许多因素。而你今天实现的 3 秒结果,明天可能会产生 8 秒并且仍在 SLA 内。

我不会深入挖掘 SLA 中的内容。

更新 1

还有许多其他方法可以减少页面加载时间。你可以开始异步思考了!将超级干净的数据空 HTML 发送到客户端,并在页面加载后通过 ajax 按需加载所有数据。

还要考虑缓存。您可以缓存(几乎)任何类型的要呈现给用户的数据。权衡“数据准确性”与“速度加载”。所以你可以缓存,甚至预缓存一些要加载的数据。我认为这将是您的方案的一个选择,因为您知道您正在寻找的 PK 和 RK - 缓存这些条目并从缓存中提供它们,而不是在每个请求上都转到表。您可以根据数据更改的可能性设置绝对到期或滑动到期。

更新 2

正如 Gaurav 提到的 - 您可以尝试并行查询表,并将结果放入缓存中。但是,并行度取决于您正在操作的核心数量。因此,如果您在单核上,则进行并行查询是没有意义的。不过,请考虑缓存和客户端数据绑定!

于 2012-08-15T09:23:21.623 回答