3

背景:SQL Serverの計算列は、単純なselect文のパフォーマンスを減速さ

は以前、私の会社は、ストアドプロシージャのwhere句でエンコードにいくつかのデータをHTMLにユーザー定義関数を使用していました。以下の例:

DECLARE @LName --HTML encoded last name as input parameter from user 

SELECT * 
    FROM (SELECT LName 
      FROM SomeView xtra 
     WHERE ((@LName <> '' 
       AND dbo.EncodingFunction(dbo.DecodingFunction(xtra.LName)) = @LName) 
      OR @Lname='')) 

私は、明確にするために、これを簡素化。

この問合せを含むストアド・プロシージャが45回連続して呼び出されたとき、62,000レコードの表の平均パフォーマンスは約85秒でした。私がUDFを削除したとき、性能はsprocを45回実行するためにわずか1秒以上に改善されました。

そこで、ビューによってアクセスされるテーブルの計算列を含むソリューションについて相談し、決定しました。SomeView計算列は、このようなテーブル定義の中に書かれていた:

[LNameComputedColumn] AS (dbo.EncodingFunction(dbo.DecodingFunction([LName]))) 

私は、テーブルを更新し、すべての62,000レコードの計算列ことを自動的にプロセスを実行しました。その後、私は次のようにストアドプロシージャのクエリを変更:私はそのストアドプロシージャを実行したとき

DECLARE @LName --HTML encoded last name as input parameter from user 

SELECT * FROM 
     (SELECT LNameComputedColumn 
     FROM SomeView xtra 
     WHERE ((@LName <> '' AND [email protected]) OR @Lname='') 

、45人の処刑の平均実行時間は約90秒に増加しました。私の変更は実際に問題を悪化させました!

私は間違っていますか?パフォーマンスを向上させる方法はありますか?

注意点として、私たちは現在、SQL Server 2000を使用していて、非常にすぐに2008 R2へのアップグレードを計画しているが、コードは、SQL Server 2000

+0

を 'OR'のポイントは何ですか? 'OR @LName = '''はテーブルから何も取得していないからです。あまり抽象化することは、みんなの時間を無駄にするだけです。私たちは、わからないことを説明できません。 –

答えて

3

Qに働かなければならないすべて:MS SQL計算列があるがパフォーマンスが遅く...

A:馬ホッケー;)

... where @LName <> '' ... 

Q:もし、 "全表スキャン" を言うことはできますか?

あなたの機能はではありません高価です。しかし、あなたは実際に指先を指す前に、より選択的な "どこ"の節を作る必要があります...

IMHO ...

提案:

  1. クエリデータが(関連するすべての "LNAMEのを" 取得最初

  2. 結果(唯一の選択 "Lnames" であなたの機能を実行します - 私は推測、 、ビューまたはテーブル全体のすべての行ではありません)

  3. ストアドプロの両方の操作(クエリとフィルタ、その後のプロセス)計算の追加cedureは

8

仮想列、まだ選択されたすべての行の実行時に計算を作成します。何が欲しいのは、計算は、挿入時に計算され、テーブルに物理的に格納されてコラム、永続化される:

[LNameComputedColumn] 
    AS (dbo.EncodingFunction(dbo.DecodingFunction([LName]))) PERSISTED