2012-03-22 5 views
1

ストアドプロシージャの1つでボトルネックと思われるものが見つかりました。 @Resultsは〜17K行のテーブル変数です。これには、TimeStamp(DateTime)列とValue(decimal)列が含まれます。関連するサブクエリのパフォーマンス

相関サブクエリのアプローチは、このタスクを達成するために私が考えることができる最初のものでしたが、パフォーマンスはで非常に悪いです。私は同じテーブルに対して相関サブクエリを使用してWHERE句を "計算"する以外に、このクエリを構造化するより良い方法を考えることはできません。どのようにこれをより良い方法で書くことができるかに関するアドバイス...

私は基本的に完全な結果のサブセットから最高値を選択しようとしています。今度は、結果レコードは、その値以下であるすべての値を数え、100を掛けて、それを@Countで割って、それが数パーセントより大きいかどうかを調べることによって、サブセットに含まれます。ここで

は、クエリです:

SELECT TOP 1 @Result = Results.Value 
FROM @Results Results 
WHERE (100.0 * (SELECT COUNT(1) 
       FROM @Results Results2 
       WHERE Results2.Value <= Results.Value)/@Count) >= @Percent 
ORDER BY Results.Value ASC 

何かアドバイスや支援をいただければ幸いです。

ありがとうございます!

+0

いいえ、Results.Valueにはインデックスがありません。結果はテーブル変数です。テーブル変数にインデックスを追加できますか? –

+1

PRIMARY KEYまたはUNIQUE制約を最初に作成したときに宣言しない限り、次のように見えます。http://sqlserverplanet.com/sql/create-index-on-table-variable - オプションでない場合は、おそらく最初に '@ temp'を'#tempResults'テーブルに格納する必要があります。 –

答えて

0

これは、達成しようとしていることを、SQLではなくユーザードメインの言葉で表現するとよいでしょう。

また、照会されるデータのスコープと構造全体は示されていませんが、パフォーマンスの決定に関与する関係が含まれている可能性があります。

この結果テーブルの変数は、独自の派生を持っています。この手法は、しばしば最適化されていない暗黙的な一時テーブルに構築されるため、危険である可能性があります。これは、クエリオプティマイザに戦略を指示しようとしているようなものです。

集計クエリから最大値を1つだけ必要とするように見えますが、これは最適化が必要です。実際には、最適化はわずか17Kレコードの問題であってはなりません。

フォームでこの言い換えることができます:

SELECT MAX(Value) 
FROM some-aggregate-query 
GROUP BY fields 
HAVING COUNT(something)/COUNT(1) * 100 > @percent 

ヒント:あなたは、手続きのために最善の政策の正反対であるSQLを(分解開始時に私の経験で、あなたは通常、間違った方向に向かっているがコード)

+0

ご回答いただきありがとうございます。私は特にテーブル変数が「最適化解除」であるというあなたのコメントに興味があります。あなたは精巧に気遣いますか?テーブル変数は一般的に悪いですか?私は実際に上記のクエリを使用して、Tempテーブルを使用し、TimeStampをPKとしてマークし、Valueにインデックスを作成し、実行時間を以前の3分の1以下にしました。何がありますか? –

0

Hmこれについて:まず、変数への行の合計数を選択します。次に、インデックスにある行(@Percent/100.0 * countOfRowsTotal)をValueで並べ替えます。

これは、1〜2回テーブルをスキャンします。

関連する問題