あなたのスキーマに応じてテーブルbig_tableを作成しました
create table big_table
(
updatetime datetime not null,
name char(14) not null,
TheData float,
primary key(Name,updatetime)
)
次に、次のコードで50,000行をテーブルに入力しました。
DECLARE @ROWNUM as bigint = 1
WHILE(1=1)
BEGIN
set @rownum = @ROWNUM + 1
insert into big_table values(getdate(),'name' + cast(@rownum as CHAR), cast(@rownum as float))
if @ROWNUM > 50000
BREAK;
END
次に、SSMSを使用して両方のクエリをテストしたところ、最初のクエリでTheDataのMAXを探し、2番目のクエリでupdatetimeのMAXを探していることがわかりました。
したがって、最初のクエリを変更して、最大更新時間も取得しました
set statistics time on -- execution time
set statistics io on -- io stats (how many pages read, temp tables)
-- query 1
SELECT MAX([UpdateTime])
FROM big_table
-- query 2
SELECT MAX([UpdateTime]) AS value
from
(
SELECT [UpdateTime]
FROM big_table
group by [UpdateTime]
) as t
set statistics time off
set statistics io off
Statistics Timeを使用すると、各ステートメントの解析、コンパイル、および実行に必要なミリ秒数が返されます
統計IOを使用して、ディスクアクティビティに関する情報を取得します。
STATISTICS TIMEおよびSTATISTICS IOは有用な情報を提供します。使用された一時テーブルなど(作業テーブルによって示されます)。また、キャッシュから読み取られたデータベースページの数を示す、読み取られた論理ページの数。
次に、CTRL + Mで実行プランをアクティブにし(実際の実行プランの表示をアクティブにします)、F5で実行します。
これにより、両方のクエリを比較できます。
これはメッセージタブの出力です
-クエリ1
テーブル 'big_table'。スキャンカウント1、論理読み取り543、物理読み取り0、先読み読み取り0、lob論理読み取り0、lob物理読み取り0、lob先読み読み取り0。
SQL Server実行時間:
CPU時間= 16ミリ秒、経過時間= 6ミリ秒。
-クエリ2
テーブル「ワークテーブル」。スキャンカウント0、論理読み取り0、物理読み取り0、先読み読み取り0、lob論理読み取り0、lob物理読み取り0、lob先読み読み取り0。
テーブル 'big_table'。スキャンカウント1、論理読み取り543、物理読み取り0、先読み読み取り0、lob論理読み取り0、lob物理読み取り0、lob先読み読み取り0。
SQL Server実行時間:
CPU時間= 0ミリ秒、経過時間= 35ミリ秒。
どちらのクエリでも543回の論理読み取りが行われますが、2番目のクエリの経過時間は35msですが、最初のクエリは最初の6msしかありません。また、2番目のクエリではtempdbの一時テーブルが使用されることにも注意してください。これは、worktableという単語で示されています。worktableのすべての値が0であっても、作業はtempdbで行われました。
次に、[メッセージ]タブの横にある実際の実行計画タブからの出力があります。
MSSQLが提供する実行プランによると、指定した2番目のクエリの合計バッチコストは64%ですが、最初のクエリは合計バッチの36%だけなので、最初のクエリに必要な作業は少なくなります。
SSMSを使用すると、クエリをテストして比較し、MSSQLがクエリをどのように解析しているか、どのオブジェクト(テーブル、インデックス、統計など)がそれらのクエリを満たすために使用されているかを正確に確認できます。
テスト時に、可能であればテストの前にキャッシュを消去することを覚えておくと、もう1つの注意事項があります。これは、比較が正確であることを保証するのに役立ちます。これは、ディスクアクティビティについて考えるときに重要です。すべてのキャッシュをクリアするために、DBCC DROPCLEANBUFFERSとDBCC FREEPROCCACHEから始めます。ただし、実際に使用している本番サーバーでこれらのコマンドを使用しないように注意してください。サーバーからすべてをディスクからメモリに効率的に読み取らせます。
ここに関連するドキュメントがあります。
- DBCC FREEPROCCACHEを使用してプランキャッシュをクリアする
- DBCC DROPCLEANBUFFERSを使用して、バッファープールからすべてをクリアします。
ご使用の環境によっては、これらのコマンドを使用できない場合があります。
10/28 12:46 pmに更新
実行計画のイメージと統計の出力を修正しました。
getdate()
ループから抜け出す必要があります