PartitionKey / RowKey列表上的Azure表存储查询速度非常慢

时间:2012-08-15 08:51:24

标签: azure azure-table-storage

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'')).....

非常标准的查询Azure表存储以获取已知PartitionKey和RowKey的列表(50)。这将需要5秒钟从服务器第一口。反正是为了加快速度吗?

2 个答案:

答案 0 :(得分: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.');
    });
}

答案 1 :(得分: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所说 - 您可以尝试并行查询表,并将结果放入缓存中。但是,parralelism程度取决于您正在操作的核心数。因此,如果您使用单核,那么进行parralel查询是没有意义的。不过,请考虑缓存和客户端数据绑定!