SQL Server 2012の2つのクエリを比較しています。目標は、最適なクエリを選択するときに、クエリオプティマイザーから利用可能な関連情報をすべて使用することです。両方のクエリは同じ結果を生成します。すべての顧客の最大注文ID。
FREEPROCCACHEおよびDROPCLEANBUFFERSを使用して各クエリを実行する前に、バッファプールをクリアしました
以下の情報を使用して、どのクエリがより良い選択ですか?
-- Query 1 - return the maximum order id for a customer
SELECT orderid, custid
FROM Sales.Orders AS O1
WHERE orderid = (SELECT MAX(O2.orderid)
FROM Sales.Orders AS O2
WHERE O2.custid = O1.custid);
-- Query 2 - return the maximum order id for a customer
SELECT MAX(orderid), custid
FROM Sales.Orders AS O1
group by custid
order by custid
統計時間
クエリ1の統計時間:CPU時間= 0ms、経過時間= 24ms
クエリ2の統計時間:CPU時間= 0ミリ秒、経過時間= 23ミリ秒
統計IO
クエリ1の統計IO:テーブル「注文」。スキャンカウント1、論理読み取り5、物理読み取り2、先読み読み取り0、lob論理読み取り0、lob物理読み取り0、lob先読み読み取り0
クエリ2の統計IO:テーブル「注文」。スキャン数1、論理読み取り4、物理読み取り1、先読み読み取り8、lob論理読み取り0、lob物理読み取り0、lob先読み読み取り0
実行計画
SELECTプロパティクエリ1
SELECTプロパティクエリ2
結論:
クエリ1
- バッチ費用48%
- 論理読み取り5
- 物理読み取り2
- 先読み読み取り:0
- CPU時間:0ミリ秒
- 経過時間24ms
- 推定サブツリーコスト:0.0050276
- CompileCPU:2
- CompileMemory:384
- CompileTime:2
クエリ2
- バッチ費用52%
- 論理読み取り4
- 物理的な読み取り1
- 先読み読み取り:8
- CPU時間0
- 経過時間23ms
- 推定サブツリーコスト:0.0054782
- CompileCPU:0
- CompileMemory:192
- CompileTime:0
個人的には、クエリ2のグラフィカルプランによるとバッチコストは高くなりますが、クエリ1よりも効率的だと思います。低い。先読み読み取りは、クエリ2の場合は8、クエリ1の場合は0です。
更新12:03
クラスター化インデックスの定義
ALTER TABLE [Sales].[Orders] ADD CONSTRAINT [PK_Orders] PRIMARY KEY CLUSTERED
(
[orderid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
非クラスター化インデックスidx_nc_custid
CREATE NONCLUSTERED INDEX [idx_nc_custid] ON [Sales].[Orders]
(
[custid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO