Azure Synapse AnalyticsのResult-set Caching機能を試してみた

#Azure Synapse AnalyticsのResult-set Caching機能
Result-set Caching（結果セットのキャッシュ）機能を有効にすると、クエリ結果がユーザーデータベースに自動的にキャッシュされるようになります。
これによって、2回目以降のクエリ実行時にキャッシュから結果セットを取得できるようになるため、高速に結果を返すことができ、なおかつ、リソース使用量の削減にもつながります。
また、Azure Synapse Analyticsではクエリの同時実行をコンカレンシースロットを消費してコントロールしますが、キャッシュから結果セットを返された場合には、コンカレンシースロットを消費する事もありません。

デフォルトはデータベースとセッションレベルでOFFとなっています。

また、キャッシュされた結果セットはSyanapse Analyticsが一時停止された後に再開されても保持されます。

##キャッシュされた結果セットが使用される条件
キャッシュされた結果セットが使用される条件があります。
・ クエリを実行しているユーザーに、クエリで参照されているすべてのテーブルへのアクセス権がある。
・ 新しいクエリと、結果セットのキャッシュを生成した前のクエリが完全に一致している。
・ キャッシュされた結果セットが生成されたテーブル内でデータおよびスキーマの変更がない。

##キャッシュされない結果セット
そもそもキャッシュされないクエリの結果セットもあります。
・　DateTime.Now() や GetDate() などクエリに変化が無くても、非決定的な関数などを使用しているクエリ。
・　ユーザ定義関数を使用したクエリ。
・　行レベルセキュリティ、列レベルセキュリティが有効になっているテーブルを使用したクエリ。
・　64KBを超える行サイズのデータを返すクエリ。
・　10GBを超えるサイズの大きなデータを返すクエリ。

##キャッシュされた結果セットの管理
結果セットのキャッシュのサイズは、最大でデータベースあたり1TBとなります。データが変更されるとキャッシュされた結果セットは自動で無効になり、以下のスケジュールで削除されます。
・　結果セットが使用されていない場合、48時間毎に削除。
・　結果セットのキャッシュが最大サイズに近づいた場合。
※基本的にLeast Recently Used（TLRU）のアルゴリズムで削除されます。

また、以下のいずれかで手動で結果セットの削除が可能です。
・　データベースの結果セットのキャッシュ機能をオフにする。
・　DBCC DROPRESULTSETCACHE を実行する。

#Result-set Caching機能まとめ
1.クライアントからSynapse Analyticsにクエリを実行。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/a84e1994-1e2d-a866-ccd3-2d24b313716a.png)

2.クエリはコンピュートノードを使用して、クライアントアプリに結果を返す。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/331f8e64-1a4a-f10a-e716-2cc674009c90.png)

3.問い合わせの結果はリモートストレージにキャッシュされるため、次の要求はすぐに処理可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/9a76f703-7df1-458b-d2b0-bd303c3cc69f.png)

4.次に実行される同じクエリはコンピュートノードをバイパスしてリモートストレージのキャッシュからデータを取得します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/a829684d-64b8-34c1-8495-99f12ce6f0fd.png)

5.リモートストレージのキャッシュは、時間、キャッシュ使用量、元となる表データへの変更操作によって定期的に削除されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/dbe18d55-4ffc-b417-b393-f6c23133bb93.png)

6.問い合わせ結果がキャッシュから削除された場合、キャッシュを再作成する必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/f7892b38-72c4-a920-808a-03ea0a8bc606.png)

#Azure Synapse AnalyticsのResult-set Caching機能を試してみた

###①現在の状態の確認

以下のSQLで現時点のResult-set Cachingの状況を確認

```
SELECT is_result_set_caching_on
FROM sys.databases
WHERE name = 'test1-synapse1';
```

結果は以下の通りFalse
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/6b9c23af-4d4a-d376-88f1-caa7348cb395.png)

###②Result-set Cachingの設定前にクエリを計測
以下のSQLを実行。

```
SELECT TOP 10 
	L_ORDERKEY, 
	SUM(L_EXTENDEDPRICE*(1-L_DISCOUNT)) AS REVENUE, 
	O_ORDERDATE, 
	O_SHIPPRIORITY
FROM CUSTOMER, ORDERS, LINEITEM
WHERE C_MKTSEGMENT = 'BUILDING' AND C_CUSTKEY = O_CUSTKEY AND L_ORDERKEY = O_ORDERKEY AND
O_ORDERDATE < '1995-03-15' AND L_SHIPDATE > '1995-03-15'
GROUP BY L_ORDERKEY, O_ORDERDATE, O_SHIPPRIORITY
ORDER BY REVENUE DESC, O_ORDERDATE;
```

実行結果は以下の通り

| 回数 | 実行時間 |
|:-----------|------------:|
| 1回目 |  72秒 |
| 2回目 |  17秒 |
| 3回目 |  18秒 |

1回目はコンパイルが走り実行時間が遅くなるが、2回目以降は17秒程度で安定。

###③Result-set Cachingの設定
masterデータベースにて以下のコマンドを実行し、Result-set Cachingを設定

```
ALTER DATABASE ＜データベース名＞
SET RESULT_SET_CACHING ON;
```

###④Result-set Cachingの設定後のクエリを計測
同じクエリを実行すると、設定後、最初の１回はキャッシュに結果セットを乗せる関係上、18秒の程度の実行時間となりましたが、次回以降のクエリの結果は以下の通り高速に結果セットをクライアントへ返します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/65485203-ae1f-5ff5-1239-cfd7aad705b0.png)

また、キャッシュされている結果セットが使われているかどうか、以下のSQLで確認が可能です。

```
SELECT *
FROM sys.dm_pdw_request_steps
WHERE command like '%DWResultCacheDb%' 
AND step_index = 0;
```

セッション単位で結果セットを使うか使わないかset文で設定する事も可能です。
※ただし、データベースで設定が有効になっている場合にのみ有効

```
SET RESULT_SET_CACHING {ON | OFF}
```



#最後に
同じクエリであれば、非常に高速に結果は帰ってきますが、今回の検証では、「同一のクエリ」か否かの判定が厳しいと感じました。
例えば、クエリの中の改行の位置や、スペースの位置が異なるだけでResult-set Cachingから結果セットを返さないようです。
使用時に、頭に入れておかないと、いけないかもしれません。