2

私には負担してください - これは複雑です。ストアドプロシージャのビューとテンポテーブルのSQL CTE

私はアパートを含むテーブルと、アパートのリースを含むテーブルを持っています。私の仕事は、リストから「最も関連性の高い」リースを選択することです。一般的に、それは直近のリースを意味しますが、日付順に比べると複雑なものがいくつかあります。私はその後、私は必要な結果を得るために、ストアドプロシージャ内の他の人の数と結合ビュー内でこの共通テーブル式クエリを作成するために私をリードしてきました

WITH TempTable AS (
    SELECT l.BuildingID, l.ApartmentID, l.LeaseID, l.ApplicantID, 
       ROW_NUMBER() OVER (PARTITION BY l.ApartmentID ORDER BY s.Importance DESC, MovedOut, MovedIN DESC, LLSigned DESC, Approved DESC, Applied DESC) AS 'RowNumber' 
    FROM dbo.NPleaseapplicant AS l INNER JOIN 
      dbo.NPappstatus AS s ON l.BuildingID = s.BuildingID AND l.AppStatus = s.Code 

) 

SELECT BuildingID, ApartmentID, LeaseID, ApplicantID 
FROM TempTable 
WHERE RowNumber = 1 

これが機能すると戻ります正しい結果。私が直面している課題は、パフォーマンスが非常に遅いことです。試験として

、私が代わりにビューを使用するストアドプロシージャ内の一時テーブルを作成し、そして多くの、より良いパフォーマンスを得ました:一見

CREATE TABLE #Relevant (
    BuildingID int, 
    ApartmentID int, 
    LeaseID int, 
    ApplicantID int, 
    RowNumber int 
) 

INSERT INTO #Relevant (BuildingID, ApartmentID, LeaseID, ApplicantID, RowNumber) 
SELECT l.BuildingID, l.ApartmentID, l.LeaseID, l.ApplicantID, 
      ROW_NUMBER() OVER (PARTITION BY l.ApartmentID ORDER BY s.Importance DESC, MovedOut, MovedIN DESC, LLSigned DESC, Approved DESC, Applied DESC) AS 'RowNumber' 
FROM dbo.NPleaseapplicant AS l INNER JOIN 
     dbo.NPappstatus AS s ON l.BuildingID = s.BuildingID AND l.AppStatus = s.Code 
WHERE (l.BuildingID = @BuildingID) 

DROP TABLE #Relevant 

これが私のところに追加されません。私は、一時テーブルがパフォーマンス上悪いと聞いています。しわは、ビューではできないWHERE句を使用してTemp Tableのクエリをよりよく制限することができるということです。テーブル内の16の建物にわたる10,000以上のリースでは、WHEREでフィルタリングする機能は、影響を受ける行を90%〜95%削除する可能性があります。

すべてのことを念頭に置いて、私がここで紛失していることが何か目に付きますか?恐ろしいパフォーマンスを引き起こす可能性のあるViewで何か問題があるのですか?それともCTEの無制限の結果セットを打ち負かすTemp Tableの小さな結果セットの問題ですか?

編集:「最も関連性の高いリース」を選択するビジネスロジックは、システム内の多くのレポートの鍵です。そのため、最初にビューの内側に配置されました。ビューは、「Write Once、Many Many」機能を提供しますが、ストアドプロシージャのTemp Tableは、システム内の他のすべてのStored Procに対して再作成する必要があります。醜い。

EDIT#2:ビューの代わりにテーブルベースの関数を使用できますか?これにより、フロントに影響を受けた行を制限し、結果セットのデータセットを他のテーブルとJOINで使用することができますか?それがうまくいっていて、まともなパフォーマンスがあれば、これは数十のストアドプロシージャでビジネスロジックを複製するのではなく、ビジネスロジックを1つの場所(関数)に保存することができます。ちょうどこの1の上に弓を置く

+0

どのバージョン(この1つは、おそらくそれらを効果的に同じ作り、とにかくインライン化されますが)

ビューは、表値関数よりも、並列実行計画の周りに少ない問題がありますか? ROW_NUMBERは2008年より優れています – gbn

+0

1.ビューからデータを選択するにはどうすればいいですか? 2.テーブル構造とインデックスを投稿してください 3.両方のクエリの実行計画を投稿してください(悪いものと良いもの) – oryol

+0

残念ながらSQL Server 2005です。ホスティング会社によって管理されるので、私はアップグレードを管理することはできません。 – Axeva

答えて

4

は、ここで私がやってしまったものです:

代わりに2つのまたは3のテーブルからすべての可能な行を結合するには、[View]を使用しての、私は同じになります。表基づく関数を作成しました基本的なクエリ。パラメータ私はそうのように、建物のIDを渡し、およびWHERE句でそれを使用の一つとして:

SELECT l.BuildingID, l.ApartmentID, l.LeaseID, l.ApplicantID, 
      ROW_NUMBER() OVER (PARTITION BY l.ApartmentID ORDER BY s.Importance DESC, MovedOut, MovedIN DESC, LLSigned DESC, Approved DESC, Applied DESC) AS 'RowNumber' 
FROM dbo.NPleaseapplicant AS l INNER JOIN 
     dbo.NPappstatus AS s ON l.BuildingID = s.BuildingID AND l.AppStatus = s.Code 
WHERE (l.BuildingID = @BuildingID) 

結果は、それが大幅が必要な結合の数を減らすということで、それがスピードアップ非常にクエリ。

次に、関数を使用するようにビューに依存するすべてのストアドプロシージャを変更し、ビンゴのパフォーマンスを大幅に向上させました。

0

副問合せの構文を使用してます。また、再書き込みができビュー:これを行う

SELECT BuildingID, ApartmentID, LeaseID, ApplicantID 
FROM 
(
SELECT l.BuildingID, l.ApartmentID, l.LeaseID, l.ApplicantID, 
       ROW_NUMBER() OVER (PARTITION BY l.ApartmentID ORDER BY s.Importance DESC, MovedOut, MovedIN DESC, LLSigned DESC, Approved DESC, Applied DESC) AS 'RowNumber' 
    FROM dbo.NPleaseapplicant AS l INNER JOIN 
      dbo.NPappstatus AS s ON l.BuildingID = s.BuildingID AND l.AppStatus = s.Code 

)subquery 
WHERE RowNumber = 1 

は、境界はどこが(ビューが使用されている場合)CTEケースISNのに対し、サブクエリに適用することができるようになります縛られていない。してください、SQL Serverの