今日、互換性レベル 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 サポート コールを開くと思います。