Azure Synapse Analytics SQLプールの実行クエリの重みづけ（重要度）

#クエリの重みづけ（重要度）が無いときに発生しうる問題
Azure Synapse Analyticsではクエリを実行する際に、実行するクエリに対してどれくらいのリソースを割り当てて実行するかで、クエリの速度や多重度に影響を与えます。
実行するクエリーに対して大きなリソースを割り当てると、クエリは高速に処理できますが、同時に多くのクエリの実行することは出来ません。
その逆で実行するクエリーに対して少ないリソースを割り当てると、クエリ実行に時間はかかりますが、同時に多くのクエリを実行する事が出来ます。

クエリの性能と同時実行性の関係については以下の記事でまとめておりますのでご参考までに。
[Azure Synapse Analytics SQLプールを高速にするリソースクラス](https://qiita.com/masahiro-yamaguchi/items/ab92934fd632716a55fa)

ここで問題となるのが、クエリの優先順位になります。
例えば、バッチ処理などを実行する場合に、バッチ処理用には大きなリソースの割り当てを行いたい場合が多いと思います。
バッチ処理の際の割り当てリソースの制御をリソースクラスで行う場合、バッチ処理用にリソースクラス「xlargerc」と言う大きなリソースクラスを割り当てるとします。

DW500cの環境ではリソースクラス「xlargerc」にてクエリを実行するためには[コンカレンシースロットが14](https://qiita.com/masahiro-yamaguchi/items/ab92934fd632716a55fa#%E5%8B%95%E7%9A%84%E3%83%AA%E3%82%BD%E3%83%BC%E3%82%B9%E3%82%AF%E3%83%A9%E3%82%B9%E3%81%A8%E6%B6%88%E8%B2%BB%E3%81%99%E3%82%8B%E3%82%B3%E3%83%B3%E3%82%AB%E3%83%AC%E3%83%B3%E3%82%B7%E3%83%BC%E3%82%B9%E3%83%AD%E3%83%83%E3%83%88%E6%95%B0)必要となります。
DW500cの[コンカレンシースロットの数は20](https://qiita.com/masahiro-yamaguchi/items/ab92934fd632716a55fa#%E3%82%B3%E3%83%B3%E3%82%AB%E3%83%AC%E3%83%B3%E3%82%B7%E3%83%BC%E3%82%B9%E3%83%AD%E3%83%83%E3%83%88)用意されています。

一方、この時に既に先にその他のクエリとしてlargercにて5本のクエリが流れていた場合、バッチ処理は空きのコンカレンシースロットが無いので待機します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/e70708ac-d272-ea8d-ea74-1563aea74a56.png)

この状態に加えて、さらにlargercのクエリを実行しようとするとこれも、同様にコンカレンシースロットに空きがないので待機します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/d45d14c4-39a1-d7b7-dc20-eec7721b094b.png)

ここで、largercで実行中のクエリの一つが終了した場合、次に実行されるのは先に待っていたxlargercのクエリではなく、largercのクエリがコンカレンシースロットに空きが出来たため先に実行されることになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/2c9c93b7-fe60-c037-85d8-791ed8f36c2f.png)

このように重要な処理であっても、コンカレンシースロットの空き具合によって、意図せず、長時間待機してしまう可能性がAzure Synapse Analyticsでは発生する可能性があります。

上記を回避するために、Azure Synapse Analyticsではクエリに対して重みづけ（重要度）を指定して優先的に実行するように設定する事が出来ます。

#重要度の種類
Azure Synapse Analytics　SQLプールでは重要度を以下のように指定できます。

**・HIGH（高）**
**・ABOVE_NORMAL（標準以上）**
**・NORMAL（標準）※デフォルト**
**・BELOW_NORMAL（標準以下）**
**・LOW（低）**

読んで字のごとく、上から順番に重要度が高くなっており、下に行くほど重要度は低くなります。

#重要度を加味した動き
重要度の設定をすると待機中のクエリの中から、次に実行されるクエリは重要度の高いクエリが優先して実行されることになります。
上述した「クエリの重みづけ（重要度）が無いときに発生しうる問題」にて記載した例の場合、xlargercのクエリを重要度を「HIGH（高）」に設定し、largercのクエリ「ABOVE_NORMAL（標準以下）」以下に設定しておけば、次に実行されるのはバッチ処理であるxlargercのクエリであり、このクエリが実行可能なコンカレンシースロットに空きが出るまで重要度が「ABOVE_NORMAL（標準以上）」以下のクエリは実行されることはありません。largercのクエリはxlargercの実行後、コンカレンシースロットに空きが出来次第実行されるという事になります。

#重要度の設定方法
今回はxlargercで動くELTLoginユーザーとmidiumrcで動くADFLoginユーザをそれぞれ準備し、ELTLoginユーザを重要度HIGH（高）、ADFLoginユーザを重要度ABOVE_NORMAL（標準以上）で設定する分類子をそれぞれ作成します。

##①ユーザの作成
```
--ユーザの作成(masterデータベースで実行)
CREATE LOGIN ELTLogin WITH PASSWORD = '＜パスワード＞';
CREATE LOGIN ADFLogin WITH PASSWORD = '＜パスワード＞';
CREATE USER ELTLogin for LOGIN ELTLogin;
CREATE USER ADFLogin for LOGIN ADFLogin;

--ユーザの作成(ユーザデータベースで実行)＆CONTROL権限の付与
CREATE USER ELTLogin for LOGIN ELTLogin;
CREATE USER ADFLogin for LOGIN ADFLogin;

GRANT CONTROL ON DATABASE::"＜データベース名＞" to ELTLogin;
GRANT CONTROL ON DATABASE::"＜データベース名＞" to ADFLogin;
```

##②重要度を指定した分類子の作成
```
--重要度をHIGH、ワークグループにxlargercを指定した分類子（wcELTQuery）を作成
CREATE WORKLOAD CLASSIFIER wcELTQuery
    WITH (WORKLOAD_GROUP = 'xlargerc'
         ,MEMBERNAME     = 'ELTLogin' 
         ,IMPORTANCE     = high);

--重要度をabove_normal、ワークグループにmediumrcを指定した分類子（wcADFQuery）を作成
CREATE WORKLOAD CLASSIFIER wcADFQuery
    WITH (WORKLOAD_GROUP = 'mediumrc'
         ,MEMBERNAME     = 'ADFLogin' 
         ,IMPORTANCE     = above_normal);
```
##③作成した分類子の確認
```
SELECT *
FROM sys.workload_management_workload_classifiers
WHERE name in ('wcELTQuery','wcADFQuery')
ORDER BY 1;
```
結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/ac35859a-1330-fb35-479e-4f669f1ca3f6.png)

##④実行したクエリの重要度の確認
以下のコマンドで実行したクエリの重要度を確認する事が可能です。

```
SELECT s.login_name, r.status, r.importance, r.submit_time, r.start_time
FROM sys.dm_pdw_exec_sessions s
JOIN sys.dm_pdw_exec_requests r ON s.session_id = r.session_id
WHERE r.resource_class is not null
ORDER BY r.start_time;
```
結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/71c6adac-e811-dbf9-541f-58a388e64162.png)

#最後に
上記はバッチ実行の重要度を高くするような例を記載しましたが、その他にも、例えば役員やCEOが見る帳票やBIから実行されるクエリの重要度を高く設定するなどをしてもいいように思いました。