5

今日、互換性レベル 80 (SQL2000) で実行されているデータベースで、Sql Server 2005 SP2 で実行されているストアド プロシージャに関する興味深いパフォーマンスの問題に遭遇しました。

proc は約 8 分間実行され、実行計画は、実際の行数が 1.339.241.423 のインデックスの使用を示しています。これは、テーブル自体の「実際の」実際の行数である 1.144.640 よりも約 1000 倍高い値です。推定行数による。したがって、クエリ プラン オプティマイザーによって与えられる実際の行数は、明らかに間違っています。

代替テキスト

興味深いことに、proc 内の procs パラメーター値をローカル変数にコピーし、実際のクエリでローカル変数を使用すると、すべてが正常に機能します。proc は 18 秒実行され、実行プランは正しい実際の行数を示します。

編集: TrickyNixon によって示唆されているように、これはパラメーター スニッフィングの問題の兆候のようです。しかし実際には、どちらの場合もまったく同じ実行計画が得られます。同じインデックスが同じ順序で使用されています。私が見る唯一の違いは、パラメーター値を直接使用するときに PK_ED_Transitions インデックスの実際の行数を増やす方法です。

dbcc dbreindex と UPDATE STATISTICS を実行しましたが、成功していません。dbcc show_statistics も、インデックスの適切なデータを示しています。

proc は WITH RECOMPILE で作成されるため、新しい実行プランを実行するたびにコンパイルされます。

より具体的には、これは高速に実行されます。

CREATE  Proc [dbo].[myProc](
@Param datetime
)
WITH RECOMPILE 
as

set nocount on

declare @local datetime
set @local = @Param

select 
some columns
from 
table1
where
column = @local
group by
some other columns

そして、このバージョンは非常に遅く実行されますが、まったく同じ実行計画を生成します (使用されたインデックスの実際の行数が多すぎることを除けば):

CREATE  Proc [dbo].[myProc](
@Param datetime
)
WITH RECOMPILE 
as

set nocount on

select 
some columns
from 
table1
where
column = @Param
group by
some other columns

何か案は?クエリプランを計算するときにSql Serverが実際の行数の値をどこから取得するかを知っている人はいますか?

更新: copat モードが 90 (Sql2005) に設定されている別のサーバーでクエリを試しました。同じ動作です。これはバグのように見えるので、ms サポート コールを開くと思います。

4

5 に答える 5

6

わかりました、ついに私はそれを自分で手に入れました。

2 つのクエリ プランは、最初は見逃していた細部が異なります。遅いものは、ネストされたループ演算子を使用して 2 つのサブクエリを結合します。そして、その結果、インデックススキャン演算子の現在の行数で高い数値が得られます。これは、単に入力 a の行数を入力 b の行数で乗算した結果です。

この場合、オプティマイザがハッシュ マッチの代わりにネストされたループを使用することを決定した理由はまだわかりません。ネストされたループの下でのインデックス スキャンの代わりに。

于 2008-10-23T11:30:47.583 に答える
2

コピー/貼り付けクエリに対してストアド プロシージャの実行計画を確認する場合、推定計画と実際の計画のどちらを使用していますか? [クエリ]、[実行プランを含める] の順にクリックしてから、各クエリを実行してください。これらのプランを比較して、違いを確認してください。

于 2008-10-22T14:18:20.443 に答える
1

パラメータスニッフィングのケースのように聞こえます。考えられる解決策とともに優れた説明を次に示し ます。

これに対処する別の StackOverflow スレッドを次に示します。 SQL Server でのパラメーター スニッフィング (またはスプーフィング)

于 2008-10-22T12:25:40.343 に答える
0

私には、統計が正しくないかのように聞こえます。インデックスを再構築しても、必ずしも更新されるわけではありません。

UPDATE STATISTICS影響を受けるテーブルの明示を既に試しましたか?

于 2008-10-22T11:38:50.627 に答える
0

sp_spaceusedを実行して、SQL Server がそのテーブルの正しい集計を取得しているかどうかを確認しましたか? SQL 2000 のエンジンは、実行計画を作成するときにそのようなメタデータを使用していたと思います。以前は、 DBCC UPDATEUSAGEを毎週実行して、急速に変化するテーブルのメタデータを更新する必要がありました。これは、SQL Server が行数データが​​正しくないために間違ったインデックスを選択していたためです。

SQL 2005 を実行していて、BOL によると、2005 年には UpdateUsage を実行する必要はなくなったはずですが、2000 互換モードにいるため、まだ必要であることがわかります。

于 2008-10-22T19:46:54.057 に答える