SE の雑記

SQL Server の情報をメインに Microsoft 製品の勉強内容を日々投稿

SQL Server で PLEASE を実装してみる

leave a comment

時代に即したMySQレの新機能:PLEASE句 が面白そうだったので、SQL Server で実装してみました。

構成としては次のようになっています。

image

SQL Server 側に通常の方法で実行されたクエリを自動的に書き換えるモジュールを入れ込む方法がぱっと思いつかなかったので、クエリを実行するクライアントと、SQL Server の間に TDS (Tabular Data Stream) の Proxy を挟んで、クライアントから実行されたクエリを強制的に書き換えて、SQL Server に流すという方式にしてみました。

TDS Proxy に対して次のようなスクリプトでクエリを実行してみます。

$con = New-Object System.Data.SqlClient.SqlConnection($env:CONSTRING)

$con.Open()

$sw = [System.Diagnostics.Stopwatch]::StartNew()
$cmd = $con.CreateCommand()
$cmd.CommandText = "SELECT 1"
[void]$cmd.ExecuteNonQuery()
$sw.stop()
Write-Host ("$($cmd.CommandText) : {0:#,##0} ms" -f $sw.ElapsedMilliseconds)

$cmd.CommandText = "PLEASE SELECT 1"
$sw.Restart()
[void]$cmd.ExecuteNonQuery()
$sw.Stop()
Write-Host ("$($cmd.CommandText) : {0:#,##0} ms" -f $sw.ElapsedMilliseconds)

$con.Close()
$con.Dispose()

一つ目が「SELECT 1」という通常の T-SQL による命令、二つ目が「PLEASE SELECT 1」という、依頼の形で T-SQL を実行しています。

実行結果がこちらになります。

image

「SELECT 1」と命令した場合は 1 秒かかり、「PLEASE SELECT 1」と依頼をしたた場合は 23ms で結果が返ってきます。

(Proxy を挟んでいるのと、プログラムから実行しているオーバーヘッドがあるので、ミリ秒で少し時間がかかっていますね)

SQLCMD からの実行を動画にしたものがこちら。


SQLCMD から実行した場合は、SQL Server 内での処理の時間となりますので 1,000 ミリ秒 (1 秒) と 0 ミリ秒となっていますね。

image

 

実際に実行されているクエリが次の内容になります。

image

「SELECT 1」という T-SQL については、命令なので、TDS Proxy がご機嫌ななめになって、「WAITFOR DELAY ’00:00:01′;」を強制的に追加して、SQL Server に対して実行されるクエリとして流します。

「PLEASE SELECT 1」という T-SQL については、依頼なので、SQL Server に気持ちよく仕事をしてもらおうと、TDS Proxy が考慮して、「SELECT 1」というクエリに変換して SQL Server に流しています。

(PLEASE という句は、SQL Server にはもちろん存在せず、そのままのクエリで SQL Server に流すと構文エラーになりますので、クライアントから流れてきたクエリから PLEASE という文字を削除して、SQL Server に流しています)

SQL Server 単体で実装する方法で通常のクエリ実行の流れで使えるのが、間に Proxy を挟むという方法しか思い浮かばなかったので、クライアントから実行されたクエリを書き換えて SQL Server に流すという方法になってしまいましたとさ。

Written by Masayuki.Ozawa

4月 1st, 2021 at 11:48 pm

Posted in SQL Server

Tagged with

Leave a Reply

Share via
Copy link
Powered by Social Snap