17

フィールドから AutoIncremented の最大値を見つけたい。(使用できる挿入後にフェッチされていない@@SCOPE_IDENTITYなど)これら2つのクエリのどちらがより高速に実行されるか、パフォーマンスが向上しますか。 Idの主キーおよびautoincrementフィールドですTable1。これは Sql Server 2005 用です。

SELECT MAX(Id) FROM Table1

SELECT TOP 1 Id FROM Table1 ORDER BY Id DESC

[編集]
はい、この場合Idはクラスター化インデックスを定義したフィールドです。
インデックスが次の場合ID DESC..
そして、はい、1の場合にパフォーマンスがどのように影響を受けるかを知っておくとよいでしょう
。IDはクラスター化されたインデックス+主キーです。
2. Id はクラスター化インデックスであり、主キーではありません。
3. Id は非クラスター化インデックス ASC + 主キーです。
4. Id は非クラスター化インデックス ASC であり、主キーではありません。
5. Id は非クラスター化インデックス DESC + 主キーです。
6. Id はクラスター化されていないインデックス DESC であり、主キーではありません。
7. ID はAutoIncrement

難しい注文ではないことを願っています!

4

7 に答える 7

10

誰も IDENT_CURRENT('Table1') に言及していません - それらをすべて吹き飛ばします - もちろん、ID列でのみ機能しますが、それ問題でした...

于 2009-08-12T15:41:39.650 に答える
9

クラスター化インデックスがある場合、2 つのクエリのパフォーマンスに実質的な違いはありません。

これは、両方がクエリ コストの 100% を負担するクラスター化インデックス スキャンを実行するためです。

インデックスを持たない列に対して 2 つのクエリを実行すると、両方の実行プランで 3 つの演算子が使用されます。

Top 句は Sort 演算子を使用し、Max 関数は Stream Aggregate 演算子を使用します。

インデックスがない場合は、MAX() 関数の方がパフォーマンスが向上します。

概念実証とテスト シナリオの完全なウォークスルーは、次の場所にあります。

パフォーマンス比較 上位 1 節 MAX() 関数

于 2009-02-26T11:59:57.500 に答える
8

理論的には、それらは同じ計画を使用し、ほぼ同時に実行されます。

実際には、

SELECT TOP 1 Id FROM Table1 ORDER BY Id DESC

おそらく a を使用しPRIMARY KEY INDEXます。

また、これは、他の列と一緒に選択することにした場合、より拡張可能ですid

実際の計画は次のようにMAX()述べています。

SELECT <- AGGREGATE <- TOP <- CLUSTERED INDEX SCAN

、一方で計画は次のようにTOP 1述べています。

SELECT <- TOP <- CLUSTERED INDEX SCAN

、すなわちaggregate省略されます。

ここでは行が 1 つしかないため、集計は実際には何もしません。

PS@Mehrdad Afshariおよび指摘したよう@John Sansomに、インデックス化されていないフィールドMAXではわずかに高速です(もちろん20、オプティマイザーが言うほどではありません):

-- 18,874,368 行

言語設定 英語
統計時間をオンに設定
統計IOをオンに設定
印刷「MAX」
SELECT MAX(id) FROM マスター
「TOP 1」を印刷
SELECT TOP 1 id FROM master ORDER BY id DESC
印刷「MAX」
SELECT MAX(id) FROM マスター
「TOP 1」を印刷
SELECT TOP 1 id FROM master ORDER BY id DESC
印刷「MAX」
SELECT MAX(id) FROM マスター
「TOP 1」を印刷
SELECT TOP 1 id FROM master ORDER BY id DESC
印刷「MAX」
SELECT MAX(id) FROM マスター
「TOP 1」を印刷
SELECT TOP 1 id FROM master ORDER BY id DESC
印刷「MAX」
SELECT MAX(id) FROM マスター
「TOP 1」を印刷
SELECT TOP 1 id FROM master ORDER BY id DESC

言語設定を us_english に変更しました。

SQL Server の実行時間:
   CPU 時間 = 0 ミリ秒、経過時間 = 1 ミリ秒。

SQL Server の実行時間:
   CPU 時間 = 0 ミリ秒、経過時間 = 1 ミリ秒。

SQL Server の実行時間:
   CPU 時間 = 0 ミリ秒、経過時間 = 1 ミリ秒。
最大

SQL Server の実行時間:
   CPU 時間 = 0 ミリ秒、経過時間 = 20 ミリ秒。

(写真: 1)
テーブル「マスター」。スキャン カウント 3、論理読み取り 32655、物理読み取り 0、先読み読み取り 447、LOB 論理読み取り 0、LOB 物理読み取り 0、LOB 先読み読み取り 0。

SQL Server の実行時間:
   CPU 時間 = 5452 ミリ秒、経過時間 = 2766 ミリ秒。
トップ1

SQL Server の実行時間:
   CPU 時間 = 0 ミリ秒、経過時間 = 1 ミリ秒。

(写真: 1)
テーブル「マスター」。スキャン カウント 3、論理読み取り 32655、物理読み取り 0、先読み読み取り 2、LOB 論理読み取り 0、LOB 物理読み取り 0、LOB 先読み読み取り 0。

SQL Server の実行時間:
   CPU 時間 = 6813 ミリ秒、経過時間 = 3449 ミリ秒。
最大

SQL Server の実行時間:
   CPU 時間 = 0 ミリ秒、経過時間 = 1 ミリ秒。

(写真: 1)
テーブル「マスター」。スキャン カウント 3、論理読み取り 32655、物理読み取り 0、先読み読み取り 44、LOB 論理読み取り 0、LOB 物理読み取り 0、LOB 先読み読み取り 0。

SQL Server の実行時間:
   CPU 時間 = 5359 ミリ秒、経過時間 = 2714 ミリ秒。
トップ1

SQL Server の実行時間:
   CPU 時間 = 0 ミリ秒、経過時間 = 1 ミリ秒。

(写真: 1)
テーブル「マスター」。スキャン カウント 3、論理読み取り 32655、物理読み取り 0、先読み読み取り 0、LOB 論理読み取り 0、LOB 物理読み取り 0、LOB 先読み読み取り 0。

SQL Server の実行時間:
   CPU 時間 = 6766 ミリ秒、経過時間 = 3379 ミリ秒。
最大

SQL Server の実行時間:
   CPU 時間 = 0 ミリ秒、経過時間 = 1 ミリ秒。

(写真: 1)
テーブル「マスター」。スキャン カウント 3、論理読み取り 32655、物理読み取り 0、先読み読み取り 0、LOB 論理読み取り 0、LOB 物理読み取り 0、LOB 先読み読み取り 0。

SQL Server の実行時間:
   CPU 時間 = 5406 ミリ秒、経過時間 = 2726 ミリ秒。
トップ1

SQL Server の実行時間:
   CPU 時間 = 0 ミリ秒、経過時間 = 1 ミリ秒。

(写真: 1)
テーブル「マスター」。スキャン カウント 3、論理読み取り 32655、物理読み取り 0、先読み読み取り 0、LOB 論理読み取り 0、LOB 物理読み取り 0、LOB 先読み読み取り 0。

SQL Server の実行時間:
   CPU 時間 = 6780 ミリ秒、経過時間 = 3415 ミリ秒。
最大

SQL Server の実行時間:
   CPU 時間 = 0 ミリ秒、経過時間 = 1 ミリ秒。

(写真: 1)
テーブル「マスター」。スキャン カウント 3、論理読み取り 32655、物理読み取り 0、先読み読み取り 85、LOB 論理読み取り 0、LOB 物理読み取り 0、LOB 先読み読み取り 0。

SQL Server の実行時間:
   CPU 時間 = 5392 ミリ秒、経過時間 = 2709 ミリ秒。
トップ1

SQL Server の実行時間:
   CPU 時間 = 0 ミリ秒、経過時間 = 1 ミリ秒。

(写真: 1)
テーブル「マスター」。スキャン カウント 3、論理読み取り 32655、物理読み取り 0、先読み読み取り 10、LOB 論理読み取り 0、LOB 物理読み取り 0、LOB 先読み読み取り 0。

SQL Server の実行時間:
   CPU 時間 = 6766 ミリ秒、経過時間 = 3387 ミリ秒。
最大

SQL Server の実行時間:
   CPU 時間 = 0 ミリ秒、経過時間 = 1 ミリ秒。

(写真: 1)
テーブル「マスター」。スキャン カウント 3、論理読み取り 32655、物理読み取り 0、先読み読み取り 0、LOB 論理読み取り 0、LOB 物理読み取り 0、LOB 先読み読み取り 0。

SQL Server の実行時間:
   CPU 時間 = 5374 ミリ秒、経過時間 = 2708 ミリ秒。
トップ1

SQL Server の実行時間:
   CPU 時間 = 0 ミリ秒、経過時間 = 1 ミリ秒。

(写真: 1)
テーブル「マスター」。スキャン カウント 3、論理読み取り 32655、物理読み取り 0、先読み読み取り 0、LOB 論理読み取り 0、LOB 物理読み取り 0、LOB 先読み読み取り 0。

SQL Server の実行時間:
   CPU 時間 = 6797 ミリ秒、経過時間 = 3494 ミリ秒。
于 2009-02-26T11:11:31.517 に答える
3

実行計画を比較するだけでわかります (Ctrl+Mクエリを編集するときに Management Studio を押します)。列に (クラスター化された) インデックスがある場合、これらのクエリは同等にパフォーマンスが高いと思いIdます。

しかし、これは全体として非常に悪い考えです。

于 2009-02-26T11:12:48.050 に答える
2

MAXの方が一般的に高速です。

どちらのクエリも、存在する場合は列のインデックスを使用します。

列にインデックスが存在しない場合、TOP 1クエリはストリーム集計の代わりにTop N Sort演算子を使用してテーブルをソートするため、処理が遅くなります。

MAX可読性も向上します。

補足: whileMAXは、インデックス付きのケースの実行プランでストリーム集約演算子を使用しますが、単一の行を処理しているだけなので、特定のコストはありません ( Actual Rows = 1)。クエリを 1 つのバッチで実行して比較し、相対的なコストを確認できます。インデックス化された場合、両方のクエリで 50% のコストがかかります。約 7000 行のテーブルでインデックスなしのケースをテストしたところ、MAX のコストが 35% であるのに対し、TOP は 65% のコストがかかります。

于 2009-02-26T11:17:12.970 に答える
2

典型的なデータセットに対して提供された 2 つの SQL ステートメントをテストしました。

SELECT MAX(Id) FROM Table1

SELECT TOP 1 Id FROM Table1 ORDER BY Id DESC

またSELECT TOP 1 Id FROM Table1 ORDER BY Id DESC、実行計画のステップが 1 つ少ないため、わずかに高速です。各クエリが実行する実行プランは次のとおりです。

テーブル 1 から最大 (ID) を選択

Clustered Index Scan >> トップ >> ストリーム集計 >> 選択

Table1 から上位 1 つの Id を選択 Id DESC で並べ替え

Clustered Index Scan >> トップ >> 選択

于 2009-02-26T12:06:58.513 に答える