2017-01-12 11 views
1

私は検索アプリケーションを持っています。 7つのフィールド(名字、名字、電話番号、市区町村、店舗番号、クレジットカード番号)があり、ユーザーがパラメータを書き込むことができ、データベース内のクライアントを見つけることができます。すべてがAND条件で作業しているので、名前が「Andy」で姓が「Larkin」の場合はAndy Larkinsなどしか見つかりません。ユーザーはフィールドを空にしておくと、名前が「Andy」のときに検索されますすべてのAndysなどのデータベースは、次のようになります。複数の結合とオプションのパラメータを使用したクエリ

enter image description here

「リレーション」テーブルには、人とお店を接続することです。 1人の住所、1店舗、複数の住所、複数の店舗、クレジットカード/複数のクレジットカードを持たなくてはなりません。今、私はすべてのフィルタリングを単一のクエリで処理する必要があります。前にいくつかの条件を確認してから別の方法でクエリを構築することはできません。

私は名字で検索すると高速です(Personテーブルの両方)が、電話番号やクレジットカード番号で検索すると時間がかかります。データベースには多くのデータがありますが、依然としてクエリが悪いです。特に、Oracleでは、クエリを書くのが得意ではありません。

ユーザーが空のままにしたパラメータはNULLに渡されるため、NVLを使用しています。すべての条件を削除してクレジットカード番号を残しておけば、高速ですので、不要な条件チェックでクエリが遅くなるということです。ほとんどの場合、条件チェックは必要ありません。ユーザーが何かを渡す場合があります。

条件を確認してからクエリを作成するオプションがあれば、必要な条件を追加するだけですが、そのオプションはありません。私はいくつかの 'IFs'をクエリに追加することを考えていましたが、それは可能でもありません。私はIF/CASE WHEN 'でしたが、私の場合に該当する例は見つかりませんでした。 - 結果(でも「DISTINCT」付き)

...WHERE (? IS NULL OR (PERSON.firstName = NVL(?, PERSON.firstName))) AND...

役立つ、と私は(人が複数のアドレスを持つことができる唯一のアドレスか何かで異なる)重複のトンを持っていないこと:私もこれを試してみました。

これは宿題ではなく、そのデータベースは他の多くのフィールドで膨大ですが、私はここでそれを簡略化しました。そこにも多くのデータがあります。手伝ってくれてありがとう。

+0

あなたは人が常に1つのアドレスを持っていると言いますから、ADDRESSとSHOPの外部結合を削除してください。 –

+0

関連しません - 左の結合は左の結合として機能しません。それらが内部結合であるかのようになります – GurV

+0

アドレス、クレジットカードなどのプライマリキー、サロゲートプライマリキーまたは自然なプライベートキーですか? PersonIdに自然インデックスがある場合、ShopIdが役立つかもしれません。 –

答えて

0

ショップでネストされたセレクトは、特に外側が結合されていることを考慮してパフォーマンスを向上させる可能性があります。以下の質問は、あなたのアイデアを得るのに十分なはずです。

重複排除については、あなたがIDを選択しているので難しいですし、「個別」は役に立たないでしょう。おそらく、構文でグループを使用する必要があり、クエリがさらに遅くなる可能性があります。

クライアントでソートを実行できる場合は、パフォーマンスに役立つ場合があります。リレーショナル・データのファンアウトやグループ化のために返されるデータ量が重要な場合は、ストアド・プロシージャを作成することが最適なオプションになる可能性があります。そのため、ほとんどの作業はデータベース上で行われ、 。

SELECT 
    p.personId, 
    p.firstName, 
    a.city, 
    a.phoneNumber, 
    shop.shopNumber 
FROM 
    PERSON p, 
    ADDRESS a, 
    CREDITCARDS c, 
    (select ss.personId, ss.shopId, ss.shopNumber from shop s, relation r 
     where s.shopId = r.shopId) as shop 
WHERE 
    p.personId = a.personId AND 
    p.personId = c.personId AND 
    p.personId = shop.personId (+) 
1

ここではいくつか考えてみましょう。

  1. 意味のないクエリには注意してください。クレジットカード番号と住所を照会するものなどがあります。その性質の質問はファントラップに分類されます。
  2. データベースに参照整合性制約を作成すると、オプティマイザは結合除去を実行できます。
  3. NVL関数を使用するのではなく、 "where句"というクエリを動的に作成できる場合は、オプティマイザにとってはるかに優れています。
関連する問題