2009-04-27 18 views
0

複雑なSQL where節があります。ケースには4つの基本的なケースがあり、それぞれに異なる要因の組み合わせがあります。 4つのケースをwhere句の別々のブランチとして持ち、各ブランチで重複した基準を繰り返すことは、わかりやすい(私の意見では)。しかし、データベースエンジンがそれをどれだけうまく最適化するかはわかりません。複雑なSQL where節:因数論理にするかどうか

ここでは、その冗長形式の表現です。私は実際の基準を手紙で置き換えました。 Aは4つの形式で提供される「分岐」基準です。特に明記しない限り、すべての式はfield='value'の形式になっています。

A1 AND B AND C AND D 
OR A2 AND B AND C AND D AND E AND F1 AND G 
OR A3 AND A3a AND B AND C AND D AND E AND F1 AND G 
OR A4 AND B AND C AND D AND F2 

AのA4を除くすべてが形field in ('value1','value2')です。 Dはfield > 'value'です。 Gはfield not in (subquery)の形式です。

ここでは、最小限の冗長形式を考慮して表現しています。

B AND C AND D AND (
    A1 
    OR (
     E AND F1 AND G AND (
      A2 
      OR (A3 AND A3a) 
     ) 
    ) 
    OR (A4 AND F2) 

私の質問は、私は最も簡単な(少なくとも冗長)論理フォーム、または、それがより多くの冗長なだけでなく、より読みやすい形式だでそれを維持するためにOKだかどうかにこの式を考慮する必要があるかどうかです。ターゲットデータベースはSybaseですが、一般的なRDMBSの答えを知りたいと思います。

答えて

2

RDBMS世界では、冗長性はあまり気にしませんが、ここでは効率が重要です。

SELECT * 
FROM mytable 
WHERE A1 AND B AND C 
UNION 
SELECT * 
FROM mytable 
WHERE A2 AND B AND C AND D AND E AND F1 AND G 
… 

私は以上7年間のSybaseに見えますが、全てではありませんでした:あなたのケースでは

、私はこのように、最高の状態としてA年代を使用してすべての4つのクエリをUNIONうメジャーRDBMSUNIONORより効率的です。

Oracleでsilimar問題へのアプローチのために私のブログでこの記事を参照してください。

ともORにおける対UNIONの比較のために、この記事でMySQL

  • Selecting friends:私は、これらのアプローチがあまりにもSybaseのために働くだろうと思いMySQL

ORのものと比較しUNIONの効率。

はまたUNIONの恩恵を受けるためにあなたの条件で使用される列にインデックスを作成する必要が

更新:

条件Gがサブクエリがあるので、おそらく、それはHASH JOINが必要であることが起こり得ます速く実行する。

SELECT * 
FROM (
     SELECT * 
     FROM foo 
     WHERE condition_set_1 
     UNION 
     SELECT * 
     FROM foo 
     WHERE condition_set_2_but_no_g 
     … 
     ) q 
WHERE G 

任意の更なる判断を行うためには、それがはるかに良いでしょう:HASH JOINは、すべてのフィルタされていない値でフルスキャンを必要とし、それはそれは可能性の高い単一フルスキャンのすべての値をフィルタリングして、HASH JOINを実行する方が良いかもしれ理由です本当にクエリ自体を見てください。

+0

良い提案です。基準Gがサブクエリを使用するという事実は、UNIONアプローチの効率性が低下するか(理論的には2つのSELECTで発生するため)、データベースエンジンはこれらのタイプのものを最適化しますか? –

+0

Gについては、クエリ自体を見て判断する必要があります。サブクエリが複雑な場合、Gはおそらく、UNIONで区切られた別のクエリで使用されるインデックスのすべてのメリットを殺す可能性があります。たぶん完全なテーブルスキャンが良いでしょう。 – Quassnoi

+0

サブクエリロジックはシンプルですが、テーブルが巨大です。サブクエリはインデックス付きフィールドで選択しているので、それほど悪くないかもしれません。私は、この特定のケースは、私はいくつかの異なる方法を試して、何が最もうまくいくかを見なければならないものだと思います。 –

0

私はそれをリファクタリングします。最終的には、複製されたロジックによって問題が発生します。 2番目の例は理解するのに数秒かかるかもしれませんが、大規模な範囲では、where節全体をすばやく見て、何が何に影響するのかを判断できるようになってから、何が起こっているのかをより簡単に確認できます。

2

もし私がM $ SQL Serverでこの問題を攻撃していたら、私は望むようにそれを書いて、クエリの実行計画を見ていきます。 (a)が遅く実行され、(b)実行計画が悪い場合、私はリファクタリングと文書化を行います。オプティマイザがクエリを実行する方法を表示するために、Sybaseのメカニズムが不明です。

+0

ポストに感謝します。 Sybaseでは、クエリを実行する前にSET SHOWPLAN ONを実行することができます。詳細は表示されます(ただし、テキストベースの形式で、SQL Serverのようなグラフィカル表現ではありません)。 –

関連する問題