時代に即したMySQレの新機能:PLEASE句 が面白そうだったので、SQL Server で実装してみました。
構成としては次のようになっています。
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 を実行しています。
実行結果がこちらになります。
「SELECT 1」と命令した場合は 1 秒かかり、「PLEASE SELECT 1」と依頼をしたた場合は 23ms で結果が返ってきます。
(Proxy を挟んでいるのと、プログラムから実行しているオーバーヘッドがあるので、ミリ秒で少し時間がかかっていますね)
SQLCMD からの実行を動画にしたものがこちら。
動作の動画 pic.twitter.com/w8xST9HsNA
— Masayuki Ozawa (@Masayuki_Ozawa) April 1, 2021
SQLCMD から実行した場合は、SQL Server 内での処理の時間となりますので 1,000 ミリ秒 (1 秒) と 0 ミリ秒となっていますね。
実際に実行されているクエリが次の内容になります。
「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 に流すという方法になってしまいましたとさ。
[…] https://blog.engineer-memo.com/2021/04/01/sql-server-%e3%81%a7-please-%e3%82%92%e5%ae%9f%e8%a3%85%e3… […]
【後で読みたい!】SQL Server で PLEASE を実装してみる | Tak's Bar
4 4月 21 at 12:33