SQL Server以外のデータベースエンジンはこのように動作しますか?
-
05-10-2019 - |
質問
私はこのようなものになるストアドプロシージャを持っています(擬似コード)
storedprocedure param1, param2, param3, param4
begin
if (param4 = 'Y')
begin
select * from SOME_VIEW order by somecolumn
end
else if (param1 is null)
begin
select * from SOME_VIEW
where (param2 is null or param2 = SOME_VIEW.Somecolumn2)
and (param3 is null or param3 = SOME_VIEW.SomeColumn3)
order by somecolumn
end
else
select somethingcompletelydifferent
end
すべてが長い間うまくいきました。突然、PARAM4が「Y」だった場合、クエリは永遠に実行され始めました。これにコードを変更する:
storedprocedure param1, param2, param3, param4
begin
if (param4 = 'Y')
begin
set param2 = null
set param3 = null
end
if (param1 is null)
begin
select * from SOME_VIEW
where (param2 is null or param2 = SOME_VIEW.Somecolumn2)
and (param3 is null or param3 = SOME_VIEW.SomeColumn3)
order by somecolumn
end
else
select somethingcompletelydifferent
また、予想されるパラメーター内で再び実行されます(40,000以上のレコードに対して15秒ほど)。これはSQL Server2005を使用しています。私の質問の要点は、SQL Serverに固有のこの特定の「機能」です。または、これはRDBMSの間で共通の機能です。
- 2年間正常に実行されたクエリは、データが成長するにつれて動作を停止します。
- 「新しい」実行計画は、論理的に同等の代替が正常に実行されているにもかかわらず、データベースサーバーがクエリを実行する機能を破壊しますか?
これはSQLサーバーに対する暴言のように思えるかもしれませんが、ある程度はある程度だと思いますが、他の人がOracle、DB2、または他のRDBMでこの種の現実を経験しているかどうかを本当に知りたいと思います。私は他の人といくつかの経験がありますが、SQL Serverでこの種のボリュームと複雑さしか見ていないので、大きな複雑なデータベースを持つ他の人が他の製品で同様の経験を持っているかどうか興味があります。
解決
いくつかの原因がある可能性があります
1)統計は最新ですか?
2)パラメーターのスニッフィングに苦しんでいる可能性があります
ところで、この種のもののために
ここで(param2はnullまたはparam2 = some_view.somecolumn2)
を見てみましょう column = @paramまたは@paramはnullを使用していますか?しないでください、それは実行しません
他のヒント
この問題のこの特定のインスタンスを想像してください。これが起こることにつながるすべての条件は、SQL Server(おそらくエディションでさえも固有です」と想像します。 (例えば、SQL Server 2008は異なる動作をします。)
しかし、これはクエリオプティマイザーの一般的な「機能」です。彼らはあなたのクエリを見て、最速を実行するものについて情報に基づいた推測をしようとします。ユーザーとして、Optimizerがインデックススキャンまたはインデックスシークを選択する(たとえば)選択した場合、直接制御はほとんどありませんが、同じものを表現する代替方法を提供して、それが実行時間の改善を呼び出すかどうかを確認することにより、間接的に影響を与える可能性があります。
クエリに影響を与える可能性のある他のスキーマ変更がなかった場合は、インデックス統計が更新されていることを確認してください。これを行うために毎週のバッチジョブを使用します。