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 の List(50) に対する Azure Table Storage への非常に標準的なクエリ。これには、サーバーからの最初のバイトに 5 秒かかります。とにかく物事をスピードアップすることはありますか?

4

2 に答える 2

2

"Or" クエリは、期待どおりに最適化されていません。このようなクエリを実行すると、テーブル全体がスキャンされます。Gaurav が提案したように、応答時間を短縮するには、これらを個別のクエリとして (並行して) 実行する必要があります。

また、パフォーマンスが SLA の範囲内にあるため、わざわざ最適化するべきではないという Astaykov の声明にも完全に同意しません。パフォーマンスはランダムではなく、SLA は一般的に上限です。パフォーマンスが重要なクエリを最適化するために時間をかけてください。この種のルックアップは、1 秒未満の時間で一貫して簡単に実行できるはずです。

編集:

どの言語で作業しているかはわかりませんが、私の家から通常 1 ~ 1.2 秒かかるように見える簡単な Node.js テストを次に示しますが、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を提供しています。さまざまなパーティションがさまざまな物理サーバーに分散される可能性が非常に高いことを念頭に置いて、結果に驚かれることはありません。

また、ストレージ 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 に答える