SQL Server 2017実行プランでこの警告を見てきました:
警告:操作により残差が発生しましたIO [sic]。読み取られた実際の行数は(3,321,318)でしたが、返された行数は40でした。
SQLSentry PlanExplorerからのスニペットは次のとおりです。
コードを改善するために、SQL Serverが関連する行にアクセスできるように、非クラスター化インデックスを追加しました。これは正常に機能しますが、通常、インデックスに含めるには(多すぎる)列が多すぎます。次のようになります。
インデックスを追加するだけで、列を含めない場合、次のようになります。インデックスを強制的に使用すると、
明らかに、SQL Serverは、キールックアップは残りのI/Oよりもはるかにコストがかかると考えています。 (まだ)多くのテストデータを含まないテストセットアップがありますが、コードが運用環境に入ると、より多くのデータを処理する必要があるため、何らかの非クラスター化インデックスが必要だとかなり確信しています。
SSDで実行する場合、キーの検索は本当にそれだけコストがかかりますか、フルファットインデックス(多くのインクルード列を含む)を作成する必要がありますか?
実行計画:https://www.brentozar.com/pastetheplan/?id=SJtiRte2X ロングの一部ですストアドプロシージャ。探す IX_BatchNo_DeviceNo_CreatedUTC
。
オプティマイザが使用するコストモデルは、a modelです。一般的に、幅広いデータベースの設計や幅広いハードウェアで、幅広いワークロードにわたって優れた結果を生み出します。
一般に、個々のコストの見積もりが特定のハードウェア構成での実行時のパフォーマンスと強く相関するとは想定しないでください。コスト計算のポイントは、オプティマイザが同じ論理演算の候補となる物理的な選択肢の間でeducatedを選択できるようにすることです。
実際に詳細に入ると、熟練したデータベースの専門家(重要なクエリの調整に時間を割く時間がある)の方が優れていることがよくあります。その点で、オプティマイザのプランの選択を出発点として考えることができます。ほとんどの場合、見つかった解は十分良いであるため、その開始点は終了点にもなります。
私の経験(および意見)では、SQL Serverクエリオプティマイザーはルックアップにコストがかかります。これは、ランダムな物理I/Oが、シーケンシャルアクセスと比較して、今日の場合よりもはるかに高価だった時代からの二日酔いです。
それでも、SSDでも、最終的にはメモリから排他的に読み取る場合でも、ルックアップは高価になる可能性があります。 Bツリー構造のトラバースは無料ではありません。明らかに、あなたがそれらの多くを行うと、コストが高まります。
含まれている列は読み取りが多いOLTPワークロードに最適です。この場合、インデックススペースの使用量と更新コストと実行時の読み取りパフォーマンスのトレードオフが理にかなっています。また、考慮すべきトレードオフもあります- 計画の安定性。完全にカバーするインデックスは、オプティマイザのコストモデルが1つの選択肢から別の選択肢にいつ移行するのかという問題を回避します。
あなたの場合、トレードオフがそれだけの価値があるかどうかを判断できるのはあなただけです。代表的なデータサンプルで両方の選択肢をテストし、情報に基づいた選択を行います。
追加した質問のコメント:
SQL Serverは残存IOのコストを知らないと言っていますか?
いいえ、オプティマイザは残りのI/Oのコストを考慮します。実際、オプティマイザに関する限り、SARG不可能な述語は別のフィルタで評価されます。このフィルターは、post-optimizationの書き換え中に残差としてシークまたはスキャンにプッシュされます。