6

次のクエリを使用して、DB から上位 100 行と 101 行を抽出し、経過時間に従って取得しますが、これは完全に異なります (2 番目のクエリは最初よりも 8 倍遅くなります)。

SELECT TOP (100) *
 FROM PhotoLike WHERE photoAccountId=@accountId AND accountId<>@accountId
 ORDER BY createDate DESC
GO

SQL Server 実行時間: CPU 時間 = 187 ミリ秒、経過時間 = 202 ミリ秒。

SELECT TOP (101) *
 FROM PhotoLike WHERE photoAccountId=@accountId AND accountId<>@accountId
 ORDER BY createDate DESC
GO

SQL Server 実行時間: CPU 時間 = 266 ミリ秒、経過時間 = 1644 ミリ秒。

最初の 2 つのケースの実行計画: 上位100と101を変数で選択

しかし、@acoundId 変数を取り除くと、次の結果が得られます。これは、この質問の最初のクエリとほぼ同じで、2 倍以上高速です。

SELECT TOP (100) *
 FROM PhotoLike WHERE photoAccountId=10 AND accountId<>10
 ORDER BY createDate DESC
GO

SQL Server 実行時間: CPU 時間 = 358 ミリ秒、経過時間 = 90 ミリ秒。

SELECT TOP (101) *
 FROM PhotoLike WHERE photoAccountId=10 AND accountId<>10
 ORDER BY createDate DESC
GO

SQL Server 実行時間: CPU 時間 = 452 ミリ秒、経過時間 = 93 ミリ秒。

2 番目の 2 つのケースの実行計画: 上位 100 と 101 を変数なしで選択

なぜこれが起こるのですか?どうすれば変数を使用してパフォーマンスを向上させることができますか?

アップデート

実行計画を追加しました。

4

3 に答える 3

2

ここでいくつかのことが起こっています。

変数を使用する場合、SQL Server は、追加した場合を除き、値をまったく盗聴しませんOPTION (RECOMPILE)

一致する行数の見積もりは、photoAccountId=@accountId実際よりもはるかに少なくなります。(2 番目のプランのインデックス シークから出ている太い線と、並列プランを使用するという決定に注意してください)。

また、 TOP 100/TOP 101は、 100 行をソートするのにスペースが必要なアルゴリズムを使用したソートと、完全なソートを実行するソートとの間のカットオフ ポイントTOP Nです。不正確な行数の見積もりは、完全なソートに割り当てられたメモリが不十分であり、tempdb.

変数を使用してクエリに追加OPTION (RECOMPILE)するだけで多少改善される可能性がありますが、「高速」プランでさえ、さまざまなインデックス作成で回避できる多くのキー検索を行っているように見えます。

于 2013-08-08T13:19:11.310 に答える
0

これはパラメーターのスニッフィングに関連している可能性があるのではないかと思います。次のクエリはどのくらいの速度で実行されますか?

DECLARE @accountIdParam int;
SELECT @accountIdParam = @accountId;

SELECT TOP (101) *
FROM PhotoLike WHERE photoAccountId=@accountIdParam AND accountId<>@accountIdParam
ORDER BY createDate DESC
GO
于 2013-08-08T12:53:53.550 に答える
0

テーブルの accountId フィールドに基づいてクラスター化インデックスを作成する必要があります。

不等式をテストすると、パフォーマンスが向上するはずです。

CREATE UNIQUE CLUSTERED INDEX [IX_MyIndexName] ON [dbo].[PhotoLike] ( accountId DESC, createDate DESC, photoAccountId DESC, )

于 2013-08-08T15:35:33.423 に答える