こんにちは、ご清聴ありがとうございました。
質問の最初の背景:
IIS7で実行し、開発したASP.netアプリケーション全体で広く使用されているインラインテーブル関数があります。これは30以上のストアドプロシージャの基礎であり、その間、通常は最大200ミリ秒で処理されます(十分な速度以上)。アプリケーションは、すべてのデータベース接続に常に同じ接続文字列を使用します。関数自体は最大10msで実行されます。
関数が使用されているストアドプロシージャを呼び出すページを呼び出すと、15秒後にタイムアウトになる場合があります。このタイムアウトはページのすべてのユーザーに適用されますが、この関数を使用するストアドプロシージャもある他のページは、これが発生している間も正常に実行されます。これは、問題のある特定のストアドプロシージャであることを示しています。ただし、これは複数のページで発生しており、複数のストアドプロシージャまたは関数自体のいずれかであることを示しています。
Webアプリケーションでタイムアウトが発生している場合でも、異なるユーザークレデンシャルを使用してManagement Studioセッションからページ上のストアドプロシージャのいずれか(またはすべて)を実行すると、200ミリ秒未満になります。
関数でsp_recompileを実行すると、ログインクレデンシャルから常にタイムアウトが「クリア」されます。
これはアプリケーションの重要な部分であるため、sp_recompileはできるだけ早く実行され、デバッグに使用できる時間はほとんどありません。また、タイムアウトを自由に再現することはできませんでした。
私はインラインテーブル関数について多くの調査を試みましたが、これがそれらに共通の問題であることを示唆するものは何も見つかりませんでした。したがって、それらは避ける必要があります。
質問:
これらのタイムアウトが関数の使用によって引き起こされている可能性はありますか、それともそれに依存するストアドプロシージャの問題であることが保証されていますか?別の言い方をすれば、ビューを使用するように、または適切なロジックをインラインでカプセル化することによって、ストアドプロシージャをリファクタリングすることには、何らかの利点がありますか?
私の推測では、これはストアドプロシージャのみであり、不明なものの最適化を追加するか、必要に応じてオプションを再コンパイルするか、パラメータをローカライズすることでこれを解決する可能性がありますが、正直なところ、基礎となるものに適用される解決策を見つけたいと思います1つの場所で修正を適用できるように機能します。
関数:
CREATE FUNCTION [dbo].[fn_ObjectIDs] (
@DateFrom AS DATETIME = NULL
,@DateTo AS DATETIME = NULL
,@Region AS INT = NULL
,@FamilyID AS INT = NULL
,@ParentID AS INT = NULL
,@ChildID AS INT = NULL
) RETURNS TABLE AS
RETURN
SELECT DISTINCT
obj.ID AS IDs
FROM tblObjects obj WITH (NOLOCK)
INNER JOIN tblFamily fam WITH (NOLOCK)
ON obj.famID = fam.famID
LEFT JOIN tblCountry cntry WITH (NOLOCK)
ON (@Region IS NOT NULL) AND (fam.countryId = cntry.countryId)
LEFT JOIN tblParent parent WITH (NOLOCK)
ON (@ParentID IS NOT NULL) AND (obj.ID = parent.objectID)
LEFT JOIN tblChild child WITH (NOLOCK)
ON (@ChildID IS NOT NULL) AND (obj.ID = child.objectID)
WHERE
obj.Visible = 1
AND obj.statusID IN (3,4,6,8)
AND ((@DateFrom IS NULL) OR (obj.CreatedDate >= @DateFrom))
AND ((@DateTo IS NULL) OR (obj.CreatedDate <= @DateTo))
AND ((@Region IS NULL) OR (cntry.regionID = @Region))
AND ((@FamilyID IS NULL) OR (obj.famID = @FamilyID))
AND ((@ParentID IS NULL) OR (parent.parentID = @ParentID))
AND ((@ChildID IS NULL) OR (child.childID = @ChildID))