1

SQL Data Warehouse の Azure コンカレンシーとワークロード管理 https://azure.microsoft.com/en-us/documentation/articles/sql-data-warehouse-develop-concurrency/を読ん で、スケールに基づいて使用できる同時クエリですが、私が理解できないため、ここで質問を提起するのは、ドキュメントの状態をテストするときに、Azure が主張する結果を得ることができないということです。クエリを同時に実行すると、シリアルで実行するのとほぼ同じ時間がかかります。

例 ここにテストの例を示します (単なるテストです) 5 つのストアド プロシージャがあり、個別に実行すると、完了するまでにそれぞれ約 1 秒かかります。したがって、5 つすべてを連続して実行すると約 5 秒かかりますが、これは予想どおりですが、5 つすべての sproc を同時に実行すると、1 秒強で完了すると予想されますが、完了するまでに約 4.5 ~ 4.7 秒かかります。

Azure の専門家が何が起こっているのか説明できますか?

リソースの競合ではないかと思いましたが、5 つの sproc が実行されている間、sys.dm_pdw_resource_waits はブロックを示していません。

sys.dm_pdw_exec_requests を実行すると、5 つの exec sproc クエリがすべて数ミリ秒以内に送信されていることがわかります。Start_time と End_compile_time についても同様です。5 つの sproc すべての end_time は再び数ミリ秒以内ですが、Total_elapsed_time は予想される 1000 ミリ秒ではなく 5000 ミリ秒に近づいています。sproc を単独で実行すると、所要時間は約 1000 ミリ秒になります。Concurrency は 5 つの sproc を同時に開始するかのように見えますが、内部的にはキューに入れられ、順番に実行されます。私はもともと、5 つの sproc に十分な 8 つのスロットを持つ DW200 でテストしていました。安全のために、最大 32 個の同時クエリを許可する DW1000 にスケールアウトしましたが (smallrc を使用しています)、この問題は解決しませんでした。

これをテストした方法は次のとおりです(DW1000を使用)

  1. 1000 レコードを 5 つの個別のステージ テーブル (ステージ 1、ステージ 2 など) にロードしました。

    CREATE TABLE dbo.Stage1
    (
         ShortId bigint NOT NULL
        ,TestName varchar(50) NOT NULL
        ,TestValue varchar(50) NOT NULL
        ,CreateDate DateTime NOT NULL 
    )
    WITH
    (
        DISTRIBUTION = HASH (ShortId)
    )
    
  2. 5 つのファクト テーブル (fact1、fact2 など) を作成しました。各テーブルにはステージと同じ 4 つの列があり、最初の列のハッシュを使用して分散されます。列ストア インデックスは含めませんでした (これは単なるテストであることを忘れないでください)。

    CREATE TABLE dbo.Fact1
    (
         ShortId bigint NOT NULL
        ,TestName varchar(50) NOT NULL
        ,TestValue varchar(50) NOT NULL
        ,CreateDate DateTime NOT NULL 
    )
    WITH
    (
        DISTRIBUTION = HASH (ShortId)
    )
    
  3. ステージからファクトにデータを挿入する 5 つのストアド プロシージャを作成しました。

    CREATE PROCEDURE dbo.TestLoad1
    AS
    BEGIN
        INSERT INTO dbo.Fact1   --this is dbo.Fact2 in sproc 2 etc...
        SELECT 
           stg.ShortId
          ,stg.PropertyName
          ,stg.PropertyValue 
          ,stg.AcquistionTime
        FROM dbo.Stage1 stg
            WHERE stg.ShortId NOT IN (SELECT ShortId from dbo.Fact1) --Fact2 etc..
    END
    
  4. C# で、5 つの接続とコマンドを作成し、BeginExecuteReader/EndExecuteReader を使用して sproc を実行するクイック テスト メソッドを作成しました。(これは単なるテストなので、スタイル/コードは許してください)

    SqlConnection cnn1 = new SqlConnection("Data Source=<server>;Initial Catalog=<database>;Persist Security Info = True;User ID =<username>;Password = <password>;Pooling = False;MultipleActiveResultSets = False;Connect Timeout = 30;Encrypt = True;TrustServerCertificate = False");
    SqlConnection cnn2 = new SqlConnection("Data Source=<server>;Initial Catalog=<database>;Persist Security Info = True;User ID =<username>;Password = <password>;Pooling = False;MultipleActiveResultSets = False;Connect Timeout = 30;Encrypt = True;TrustServerCertificate = False");
    SqlConnection cnn3 = new SqlConnection("Data Source=<server>;Initial Catalog=<database>;Persist Security Info = True;User ID =<username>;Password = <password>;Pooling = False;MultipleActiveResultSets = False;Connect Timeout = 30;Encrypt = True;TrustServerCertificate = False");
    SqlConnection cnn4 = new SqlConnection("Data Source=<server>;Initial Catalog=<database>;Persist Security Info = True;User ID =<username>;Password = <password>;Pooling = False;MultipleActiveResultSets = False;Connect Timeout = 30;Encrypt = True;TrustServerCertificate = False");
    SqlConnection cnn5 = new SqlConnection("Data Source=<server>;Initial Catalog=<database>;Persist Security Info = True;User ID =<username>;Password = <password>;Pooling = False;MultipleActiveResultSets = False;Connect Timeout = 30;Encrypt = True;TrustServerCertificate = False");
    
    SqlCommand cmd1;
    SqlCommand cmd2;
    SqlCommand cmd3;
    SqlCommand cmd4;
    SqlCommand cmd5;
    IAsyncResult result1;
    IAsyncResult result2;
    IAsyncResult result3;
    IAsyncResult result4;
    IAsyncResult result5;
    SqlDataReader reader1;
    SqlDataReader reader2;
    SqlDataReader reader3;
    SqlDataReader reader4;
    SqlDataReader reader5;
    
    cnn1.Open();
    cnn2.Open();
    cnn3.Open();
    cnn4.Open();
    cnn5.Open();
    
    cmd1 = new SqlCommand("dbo.TestLoad1", cnn1);
    cmd2 = new SqlCommand("dbo.TestLoad2", cnn2);
    cmd3 = new SqlCommand("dbo.TestLoad3", cnn3);
    cmd4 = new SqlCommand("dbo.TestLoad4", cnn4);
    cmd5 = new SqlCommand("dbo.TestLoad5", cnn5);
    
    cmd1.CommandType = CommandType.StoredProcedure;
    cmd2.CommandType = CommandType.StoredProcedure;
    cmd3.CommandType = CommandType.StoredProcedure;
    cmd4.CommandType = CommandType.StoredProcedure;
    cmd5.CommandType = CommandType.StoredProcedure;
    
    result1 = cmd1.BeginExecuteReader(CommandBehavior.SingleRow);
    result2 = cmd2.BeginExecuteReader(CommandBehavior.SingleRow);
    result3 = cmd3.BeginExecuteReader(CommandBehavior.SingleRow);
    result4 = cmd4.BeginExecuteReader(CommandBehavior.SingleRow);
    result5 = cmd5.BeginExecuteReader(CommandBehavior.SingleRow);
    
    reader1 = cmd1.EndExecuteReader(result1);  //this is where the code waits for 5 seconds
    reader2 = cmd2.EndExecuteReader(result2);
    reader3 = cmd3.EndExecuteReader(result3);
    reader4 = cmd4.EndExecuteReader(result4);
    reader5 = cmd5.EndExecuteReader(result5);
    
    reader1.Close();
    reader2.Close();
    reader3.Close();
    reader4.Close();
    reader5.Close();
    

この C# コードをデバッグする場合、reader1 = cmd1.EndExecuteReader(result1); という行に到達するまで、各ステートメントは 1 ミリ秒未満です。ここでは、4 ~ 5 秒待機してから次に進み、その後のすべての行が再び高速になります (<1ms)。

その遅延の間に select * from sys.dm_pdw_exec_requests を実行すると、5 つの要求すべてがキューに入れられて実行されていることがわかります。クエリの再実行を続けると、クエリの実行時間が長くなり続け、突然 (約 5 秒) 5 つのクエリすべてが完了したと表示されます。

私が間違っていること、または Azure SQL DW が内部で行っていることを説明する際に、どんな助けもいただければ幸いです。

ありがとうございました

4

1 に答える 1

2

SQL Data Warehouse では、1 つのクエリですべての CPU または IO を使用できます。クエリがリソースを完全に利用できる場合、同じリソースに対して競合する別のクエリを追加すると、両方の実行が遅くなります。つまり、CPU を 100% 使用するクエリがあり、同時に 100% を使用する別のクエリを実行すると、両方のクエリに 2 倍の時間がかかります。これの利点は、1 つのクエリが可能な限り高速に実行され、異なるリソースで競合する 2 つのクエリも可能な限り高速に実行されることです。すべてのクエリが本質的に同一である上記のようなテストを実行する場合、テストを連続して実行する場合も同時に実行する場合も、同じ時間がかかることが予想されます。

結果をさらに調査するには、監視に関する記事が役立つ場合があります。sys.dm_pdw_exec_requests を見るだけでなく、sys.dm_pdw_request_steps (分散 SQL ステップによる実行時間) も調べてみてください。これは、5 秒の大部分を占めていると予想されます。また、sys.dm_pdw_sql_requests (分散による実行時間) )。

ところで、上記で、テスト用に列ストア インデックスを追加しなかったと述べました。SQL DW では、既定のテーブルの種類は clustered columnstoreです。このインデックスを削除するには、WITH 句を次のように変更します...

WITH ( ディストリビューション = ハッシュ (ShortId), ヒープ )

お役に立てれば。

于 2016-09-24T16:02:05.593 に答える