大きいデータの時の OFFSET FETCH は定数でクエリ書いた方が有利そう?

以前このブログでも紹介した、 OFFSET FETCH を使って気付いたメモです。
OFFSET FETCH の紹介 - お だ のスペース

大きいデータに対して、OFFSET FETCH を使った時に遅いなーと思って色々試してると、OFFSET と FETCH の値をパラメータ化してるかしてないかで実行プランと実行速度が変わることに気付きました。

検証した環境 Azure SQL Database Basic 互換性レベル 130 です。
テスト用のテーブルに 50万件ほどデータを入れます。

create table [PagingTest] (
  [ID] int not null primary key, 
  [SortDate] date not null
) 

with [cte] as (select 1 as [seq] union all select [seq] + 1 from [cte] where [seq] <= 500000)
insert into [PagingTest]
select [seq], dateadd(day, [seq] % 100, getdate())
from [cte]
option (maxrecursion 0)

これに対して 同じ結果を返す2つのクエリを実行します。

declare @start int = 4
declare @count int = 10

-- set statistics time on
-- set statistics io on

select * 
from [PagingTest] 
order by [SortDate] 
offset 4 rows fetch next 10 rows only

select * 
from [PagingTest] 
order by [SortDate] 
offset @start rows fetch next @count rows only

これの実行プランは以下です。
変数を使ってない方のクエリは、Sort が Top N Sort になっていますが、変数を使っている方のクエリは普通の Sort です。
で、データ量が大きいと Top N Sort の方が有利になるよというお話しです。

というわけで、実際に以下を実行してみます。

select count(*) from [PagingTest]

declare @start int = 4
declare @count int = 10

set statistics time on
set statistics io on

select * 
from [PagingTest] 
order by [SortDate] 
offset 4 rows fetch next 10 rows only

select * 
from [PagingTest] 
order by [SortDate] 
offset @start rows fetch next @count rows only

実行結果のメッセージを確認すると、elapsed time が一桁違ってました。
具体的な数値は検証クエリをみなさんで流してもらえば確認出来ると思います。

面白いのは start の値が大きくなるほど、Top N Sort も効きが弱くなってくるんですね。
350000 とかで試すと両方のクエリの実行時間はほとんど変わらないくらいになっていました。
まあなんとなく想像つきますよね。

というわけで、後ろのページになると差は無くなりますが、前の方のページだと結構変わってきそうです。
ただプランキャッシュは増えそうですね。

クエリ全文

create table [PagingTest] (
  [ID] int not null primary key, 
  [SortDate] date not null
) 

with [cte] as (select 1 as [seq] union all select [seq] + 1 from [cte] where [seq] <= 500000)
insert into [PagingTest]
select [seq], dateadd(day, [seq] % 100, getdate())
from [cte]
option (maxrecursion 0)

select count(*) from [PagingTest]
declare @start int = 4
declare @count int = 10

-- set statistics time on
-- set statistics io on

select * 
from [PagingTest] 
order by [SortDate] 
offset 4 rows fetch next 10 rows only

select * 
from [PagingTest] 
order by [SortDate] 
offset @start rows fetch next @count rows only

drop table [PagingTest]

JDBC Driver 4.2 / 6.0 Preview for SQL Server は Java 7以下で動きませんよ!

JDBC Driver4.2 (Preview) for SQL Server は JDK8 のみ動作する? - お だ のスペース
JDBC Driver 4.2 for SQL Server がリリースされてました - お だ のスペース

以前にも書いたのですが、JDBC Driver 4.2 以降は、Java 7以下は動作しません。
System Requirements for the JDBC Driver
の sqljdbc42.jar の箇所に、

Requires a Java Runtime Environment (JRE) 8.0. Using JRE 7.0 or lower will throw an exception.

と記載があります。

今さらこんなの書いたのは、公式?のブログに 4.2 系のサポートが 5, 6, 7, 8 と載ってたので。
SQL Server データアクセスレイヤーについて – Microsoft Japan Data Platform Tech Sales Team Blog

もちろんブログも悪いのですが、大元のダウンロードページのシステム要件が間違っているのが問題。
Download Microsoft JDBC Driver 6.0 for SQL Server、Microsoft JDBC Driver 4.2 for SQL Server、Microsoft JDBC Driver 4.1 for SQL Server、および Microsoft JDBC Driver 4.0 for SQL Server from Official Microsoft Download Center

フィードバック上げた気がするけど、も一回上げときました。
bug JDBC Driver 4.2 download page system requirements. | Microsoft Connect

※2016/08/03 追記
今見たらダウンロードページのシステム要件が修正されてました。良かった~。

Swagger 用の IDE RepreZen API Studio を試してみた

Twitter の DM で使ってみてよって言われたのでちょっと触ってみました。
RepreZen API Studio: A true IDE for Swagger–OpenAPI

使うには、名前とメールアドレスと会社URLが要りましたが、会社URLは必須じゃなさそう(個人のURL)でもいけました。

必要要件は JDK 1.7 以上なので、みなさん大丈夫ですね。
Java がいるということで、ベースは Eclipse でした。

Free Trial は、15日間です。

サイトのトップを見た感じでは、yaml 書いたら、右側のペインに Swagger UI が表示されていく風です。

これだけ見たら正直要らないかなと思いました。
自分が作るなら JAX-RS なりで WEB API 作ってから Swagger の json なり yaml を吐く方法を取るかなと。*1

なので、これを使うシチュエーションが思い浮かばなかったのですが、サンプルの動画を見て試してみるとこれが結構面白い!

yaml から Swagger UI 表示するのは当然なんですが、そこからサーバー側やクライアント側のコードを自動生成してくれます!!

自動生成するターゲットも色々ありました。

取り合えず、JAX-RS Server (Jersey) と C# クライアントを自動生成してみましたが、初回は Maven のダウンロードで結構時間掛かります。
また JAX-RS が Jersey っていうのもなんかアレ。REST Easy が良かった。

動かしては無いですが、それっぽいソースは吐けています。
あと、新規追加を選ぶと何故か Xtend の文字が!

これだけで使ってみようと思いますよね!

API 作る時に試してみたいなぁと思いました。

というわけで、あまり触れてないですが RepreZen API Studio の紹介です。

*1:実際に Swagger 使った際も、JAX-RS のクラスから、json 吐いたし。

SQL Server Developer Edition が無償で提供されていました

3ヶ月ほど前でしょうか。見落としてました。。

SQL Server Developer Edition が無償提供されます | SQL Server サポート の中の人
Microsoft SQL Server Developer Edition is now free | SQL Server Blog

Visual Studio Dev Essentials ユーザーに Developer Edition が提供されているようです。
Free Developer Offers | Visual Studio

良い感じですねー。

SQL Server Management Studio ( SSMS ) 2016 のダウンロード場所

2016 の SSMS ってGAしてないの?みたいなのをTwitter で幾つか見かけたのでリンク貼っときます。

Download SQL Server Management Studio (SSMS)
サイトは US ですが、リンク先から落とせるインストーラーは、SSMS-Setup-JPN.exe でした。

7/2(土) CLR/H で SQL Server / T-SQL のお話しします

CLR/H #clrh101 ~日本の夏、MR の夏~ - connpass

ひょんなことから CLR/H でお話しさせていただくことになりましたー。

何話すか悩んだのですが、ベタに SQL Server 絡みのお話しにしました。
久々の登壇(今年入って初)で、準備やらバタバタしてますがちゃんとお話し出来るよう頑張ります!

他にも旬な HoloLens、PoserShell 5.0 と面白そうなので是非ご参加を~。