1

SQLServer2005データベースがあります。これらの個別の値に対して関数を呼び出すことに加えて、個別の値を取得する必要があります。関数呼び出しが含まれている場合に、個別がどのように機能するかはわかりません。たとえば、次のクエリがあります。

SELECT DISTINCT a, b, c, fcn_DoSomething(a, b, c) AS z FROM users

関数(fcn_DoSomething)は、個別の値ではなく、テーブル内のすべての値に対して呼び出されていると思います。私は正しいですか?もしそうなら、どうすればa、b、cの異なる値でのみ関数を呼び出すクエリを書くことができますか?私は1つのオプションが一時的なテーブルを使用することであることを知っています、しかし誰かがより良いアイデアを持っているならそれは素晴らしいでしょう。

ありがとう

4

2 に答える 2

2

これは私に興味をそそられたので、私は少し基本的なテストをしました。いくつかの異なる値といくつかの繰り返し値を含む小さなテーブルを作成しました。これは、文字列の連結を行うだけの関数であり、次の実行プランを確認しました。

Go
DBCC DROPCLEANBUFFERS 
DBCC FREEPROCCACHE 


select distinct cola, colb, dbo.sillyfunc(cola, colb)
from distincttest

--Clear the cache
Go
DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE 

select cola, colb, dbo.sillyfunc(cola, colb)
from (select distinct cola, colb from distincttest) as t

この場合、実行プランは、最初のプランがすべての単一行に対して連結関数を実行したことを明確に示していましたが、2番目のプランは最初に個別の値の並べ替えを実行し、次に関数を実行しました。ただし、少数の行の場合、実行時間は同じであり、一緒に実行すると、クエリリソース全体の50%を使用して各行が表示されました。

そこで、数十万の繰り返し行を追加しました。もう一度やり直しました。これによりクエリプランが変更され、以前の並べ替えではなく、区別を取得するためにハッシュ一致が実行されました。現在、区別を選択するように強制された2番目のバージョンでは、最初に10倍以上高速に実行されました。

最後に、SQL Serverでsillyfuncが非決定論的(0を返す)としてマークされているためである可能性があると考えたため、組み込み関数で決定論的と見なされるpatindexselect OBJECTPROPERTYEX(object_id('dbo.sillyfunc'), 'isdeterministic')に切り替えました。これにより、最初のバージョンではすべての行に対して、2番目のバージョンではいくつかの異なる行に対して関数が呼び出されても同じ結果が得られました。

したがって、さらにテストを行うと、オプティマイザーがより洗練された処理を実行するように誘導する状況が見つかる可能性がありますが、関数が呼び出される前に個別を適用する場合は、サブクエリ、CTE、または関数がアクセスできるものを制限するための一時テーブル。

于 2012-09-11T21:53:13.847 に答える
1

これにより、関数が個別の値でのみ呼び出されるようになります。

select *, fcn_DoSomething(a, b, c) 
from
 (select distinct a,b,c FROM users) v

ただし、関数呼び出しは最適化されると思いますので、違いはないかもしれません。試してみる。

于 2012-09-11T20:57:56.203 に答える