2009-03-11 20 views
6

パフォーマンスのために関数の結果をメモしたい、つまり、関数の引数にインデックスされたキャッシュを遅延して読み込む必要があります。私が関数を初めて呼び出すとき、キャッシュは入力引数のための何も持っていないので、それを計算し、それを返す前にそれを格納します。後続の呼び出しはキャッシュを使用するだけです。SQL Server 2000のキャッシング関数の結果

しかし、SQL Server 2000では、機能が「確定的」であるという愚かな恣意的なルールがあるようです。 INSERT、UPDATE、および通常のストアドプロシージャ呼び出しは禁止されています。ただし、拡張ストアドプロシージャは許可されています。これはどうやって決定的ですか?別のセッションでデータベースの状態が変更された場合、関数の出力は変更されます。

私は気が狂っています。私はキャッシュをユーザーに透過的にできると思っていました。これは可能ですか?拡張ストアドプロシージャを展開する権限がありません。

EDIT:

この制限は、2008年にまだあるあなたは神のために、RANDを呼び出すことはできません!

キャッシュは私のDBで実装されます。キャッシュは...キャッシングに使用されるすべてのデータストアである

EDIT:

が関数に同じ引数が基本となるデータへの変更の外に、異なる結果が得られます何の例はありません。これはBIプラットフォームであり、唯一の変更はスケジュールされたETLからのもので、その時点でキャッシュテーブルをTRUNCATEします。

O(n^4)のオーダーのI/O集約時系列計算です。私は基礎となるテーブルまたはインデックスを変更する義務を持っていません。また、これらの関数の多くは同じ中間関数を使用し、キャッシングを使用することができます。

UDFは、データベースの状態の変化を考慮しない限り、真に確定的ではありません。ポイントは何ですか? SQL Serverはキャッシュされていますか? (皮肉なことに)SQL Serverがキャッシュしている場合は、スキーマにバインドされているテーブルの変更が期限切れになっている必要があります。それらがスキーマにバインドされている場合、関数が変更するテーブルをバインドしないのはなぜですか?なぜprocsが許可されていないのか分かります。スキーマバインドprocsだけです。そして、なぜ、拡張ストアドプロシージャを許可するのですか?決定論を確実にするためにそれらが何をするかは、おそらく追跡できません!アー!

EDIT:

私の質問は:怠惰ビューで使用することができるように、関数の結果をキャッシュする方法はありますか?

+0

申し訳ありませんが、元の投稿から「最初から」キャッシュを作成していたことがわかりませんでした。どのように同じ関数が同じ議論で異なる結果を返すべきである場合に対処するつもりでしたか? –

+0

何があなたの質問ですか? –

答えて

2

確定性は、同じ入力が時間とデータベースとは無関係に同じ出力を返すことを意味します。

SQL Server(任意のバージョン)はUDFのキャッシングを行いません。UDFを1行で2回呼び出すことは避けられますが、それだけです。あなたはとても効果的があることを値の使用可能な個別のサブセットは所与のセットのために返却できる場合

リファクタリングUDF:私が使用した

1つのトリックは、(私はここにSO上でそれを掲載思う)にあります入力。数値計算では、渡された値からUDFの内部で掛け合わされるのではなく、UDFの外側で掛け合わされる係数または率を返すようにロジックをリファクタリングすることがあります。

DISTINCT行セットを介してUDFを呼び出し、その結果を一時テーブルにキャッシュします。17,000,000行のセットで100,000タプルのパラメータを持つUDFのみを呼び出す場合、これはと非常に効率的です。がはるかに効率的です。

一時テーブルへのJOIN(基本的にコードベースのロジックからテーブルベースのロジックへの変換)で値を取得します。

この表は、必要に応じて再利用することも、保管することもできます。

最初にLEFT JOINingを実行して、キャッシュされていないエントリを見つけることができます。

これは、単一行のテーブル値のUDFとスカラーUDFの両方で機能します。私は主に、それをテーブル値のUDFに使用しています。 SQL Server 2005には、UDFのパフォーマンスに対処するための修正プログラムがあります。本番環境に展開する前にmthe DBAがテストするのを待っています。

+0

まず、キャッシュのポイントは遅延計算です。テーブルをより多く埋め込むことは目的を破る。第二に、このアプローチはすべて、UDFからキャッシングを移動することです。 UDFをスキップしてprocを使用するだけではどうですか?最後に、関数をビューで使用することができますが、これは利点がありません。 – alyssackwan

+0

私は、すべてのものと、潜在的なUDFの結果のみを完全に取り込みます。いくつかは複数回呼び出され、0回呼び出されることはありません。それはキャッシュではなく、プリキャッシュです。節約は実際にルックアップテーブルを作成するために実際に行われたUDF呼び出しの違いによって直接測定できます。トレードオフはストレージです。 –

関連する問題