【问题标题】:Very Slow on Azure Table Storage Query on PartitionKey/RowKey List对 PartitionKey/RowKey 列表的 Azure 表存储查询非常慢
【发布时间】:2012-08-11 13:55:03
【问题描述】:

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 秒。有没有办法加快速度?

【问题讨论】:

    标签: azure azure-table-storage


    【解决方案1】:

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

    我也完全不同意 Asaykov 的说法,即您不应该费心优化,因为您的性能在 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.');
        });
    }
    

    【讨论】:

    • 我想通过 PartitionKey 和 RowKey 获得 50 个项目。你建议我发出 50 个并行 http 调用吗?或者无论如何“不触发全表扫描”一次调用获得 50 个项目?
    • @EricYin - 考虑到您的数据排列方式,如果没有表扫描,就不可能一次调用所有数据。如果您重新排列了您的密钥,以便您想要的项目都在一个分区中,您可以通过分区扫描或可能的范围扫描来做到这一点。但其可行性取决于您的数据。
    • @breischl 是对的。是的,我建议 50 个并行 HTTP 调用。
    • @smarx 谢谢。在我的本地机器中,50 个呼叫比 1 个(10M ADSL)慢得多。明天我会在 Cloud 上试试看。
    • Begin/End 使用完成端口,而 Tasks 尝试为每个请求创建一个线程。 Begin/End 速度快了一个数量级或更多。
    【解决方案2】:

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

    同样根据Storage SLA,进行表操作:

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

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

    必须在 2 秒内完成处理

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

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

    更新 1

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

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

    更新 2

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

    【讨论】:

    • :( 太可悲了。现在所有的网页设计规则都说你应该在 2 秒内加快页面加载速度。这似乎是 Azure 不可能完成的任务,我已经在每个页面中将查询减少到两个,但平均我在 5 秒内呈现我的页面 :( 这非常慢
    • 由于您的所有查询都在 PartitionKey 和 RowKey 组合上(PartitionKey = something 和 RowKey = someotherthing),您是否可以尝试分别并行触发这些查询而不是执行“OR”并在你的应用程序代码,看看这是否有什么不同。
    • 为了获得 50 个项目,并避免全表扫描,理论上我需要并行 50 个 http 调用!我试过这不是一个好主意。而且,由于数据库中有数百万个项目,我无法缓存它们,我将 CDN 用于生成的页面。问题是第一次查看花了很长时间。有没有办法“不触发全表扫描”并一次调用 50 个项目?
    猜你喜欢
    • 2016-07-27
    • 1970-01-01
    • 2021-10-16
    • 1970-01-01
    • 2016-06-18
    • 1970-01-01
    • 2012-09-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多