これは古い投稿ですが、私が現在行っていたこと (2013 年) に関連していました。より大きなデータセット (ほとんどの DB で一般的) を取得すると、さまざまなクエリのパフォーマンス (実行計画を見る) が多くのことを示します。最初に「TALLY テーブル」を作成してランダムに数値を生成し、次に任意の式を使用して「MyTable」のデータを作成します。
CREATE TABLE #myTable(
[id] [int] NOT NULL,
[business_key] [int] NOT NULL,
[result] [int] NOT NULL,
PRIMARY KEY (Id)
) ON [PRIMARY];
; WITH
-- Tally table Gen Tally Rows: X2 X3
t1 AS (SELECT 1 N UNION ALL SELECT 1 N), -- 4 , 8
t2 AS (SELECT 1 N FROM t1 x, t1 y), -- 16 , 64
t3 AS (SELECT 1 N FROM t2 x, t2 y), -- 256 , 4096
t4 AS (SELECT 1 N FROM t3 x, t3 y), -- 65536 , 16,777,216
t5 AS (SELECT 1 N FROM t4 x, t4 y), -- 4,294,967,296, A lot
Tally AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) N
FROM t5 x, t5 y)
INSERT INTO #MyTable
SELECT N, CAST(N/RAND(N/8) AS bigINT)/5 , N%2
FROM Tally
WHERE N < 500000
次に、3 種類のクエリを実行してパフォーマンスを確認します (SQL Server Management Studio を使用している場合は、[実際の実行計画] をオンにします)。
SET STATISTICS IO ON
SET STATISTICS TIME ON
----- Try #1
select 'T1' AS Qry, id, business_key,
result
from #myTable
where id in
(select max(id)
from #myTable
group by business_key)
---- Try #2
select 'T2' AS Qry, id, business_key,
result
from
(select id,
business_key,
result,
max(id) over (partition by business_key) as max_id
from #mytable) x
where id = max_id
---- Try #3
;with cteRowNumber as (
select id,
business_key,
result,
row_number() over(partition by business_key order by id desc) as RowNum
from #mytable
)
SELECT 'T3' AS Qry, id, business_key,
result
FROM cteRowNumber
WHERE RowNum = 1
掃除:
IF OBJECT_ID(N'TempDB..#myTable',N'U') IS NOT NULL
DROP TABLE #myTable;
SET STATISTICS IO OFF
SET STATISTICS TIME OFF
実行計画を見ると、「試行 1」の「クエリ コスト」が最も高く、CPU 時間が最も短いことがわかりますが、「試行 3」は読み取りが最も少なく、CPU 時間もそれほど悪くありません。読み取りを最小限に抑えるには、CTE メソッドを使用することをお勧めします