2016-09-21 3 views
1

結果セットを小さなサイズに制限するかどうかを決定するフラグがあります。クエリ自体は膨大で、保守がひどいので、コピー/貼り付けはしたくありません。何が最善の方法ですか?私は私が遊んだいくつかの選択肢を持っているが、彼らは私にはハックっぽいのようだ:SQL ServerのTOP(@x)または単に "all"行を選択する方法(SET ROWCOUNTなし)

可能性#1

SELECT TOP (
    CASE WHEN @flag = 1 THEN @limit ELSE @someHugeNumber END 
) (...) 
FROM (...) hugeQuery; 

可能性#2

DECLARE @rc INT = CASE WHEN @flag = 1 THEN @limit ELSE 0 END; 
SET ROWCOUNT @rc; 
SELECT (...) FROM (...) hugeQuery; 

がありますより良い方法ですか?パフォーマンスはどうですか?ヘルプは高く評価しました!

+1

TOPのcase式で何が問題になっていますか?私はここでROWCOUNTを使用するファンではありません。なぜなら、必要なときに2つのステートメントを使用することを意味するからです。 –

+0

ほとんどの場合、私は最大値を定義したくないです。その事件が実際に「すべてを」と意味することを意味し、効果的に私は何十億という言葉を要求しているだけでは、あまり読みにくくない。それは私のにおいがする。 – Dave

+0

'set rowcount'を使用すると、クエリ内で実行されるすべてのステートメント(ストアドプロシージャ呼び出し、ビュー、トリガなど)に適用されます。本当にそれが欲しいですか?あなたの言われたように、「トップ(n)」が間違っていて、読みやすさは主観的です。 – ajeh

答えて

3
WITH q AS 
     (
     /* my huge query */ 
     ) 
(
SELECT TOP (@limit) 
     * 
FROM q 
WHERE @flag = 1 
) 
UNION ALL 
(
SELECT * 
FROM q 
WHERE @flag = 0 
) 
ORDER BY 
     somefield 
OPTION (RECOMPILE) 

OPTION (RECOMPILE)は、オプティマイザが@flagの値を盗聴し、いずれかのクエリを最適化することになるだろう。ただし、各呼び出しでクエリを再コンパイルする必要があります。

ただし、この2つのクエリは、マージユニオンアルゴリズムを使用して連結されていることが最も一般的です。このアルゴリズムは、実際にはほぼ同じパフォーマンス(クエリの1つが常に空であるため)巨大なクエリ出力はsomefieldにソートされます。

+0

またはあなたは未知のために最適化することができます。しかしこれはトップNよりどのように優れていますか? – ajeh

+0

@ajeh:optim for unknownは、オプティマイザでキャッシュされたプランを作成し、パラメータの値についての仮定を作成しません。それでも両方のクエリを実行する必要があります。 – Quassnoi

+0

@Quassnoi、申し訳ありませんが、以下の質問をしてください。私はシナリオをどのように扱うべきか分かりません。親切な一見。 https://stackoverflow.com/questions/46285924/which-kind-of-table-design-best-suuitable-for-normalization-in-sql-server親切にも、より良い解決策を提案します。 – RGS

関連する問題