2012-01-09 18 views
0

私はこのようになり、深い階層モデルを持っている:最適化階層問合せ

は アカウント - >イベント - - >チケット

そして、私は、クエリを実行する必要がある - >ゲストが を示しています>が を会場

クエリ:

それは次のようになりますので、私は、親のゲストリストやイベントや会場ORアカウントに基づいてチケットを選択する場所
select * from user_detail ud, venue v, event e, guest_list g, ticket t 

where 

    t.guest_list = g.id 
    and g.event = e.id 
    and e.venue = v.id 

    and (
     ud.guest_list = t.guest_list 
     or ud.event = g.event 
     or ud.venue = e.venue 
     or ud.account = v.account 
    ) 

これはもちろん非常にコストのかかるクエリです。私は何百万というチケットを持っているので、これは私が望んでいたようにうまく動作していません。

非理想的なソリューション(チケットレベルで冗長親への参照を格納)

私は考えています解決策は、チケット行の直接の親が、すべての超両親だけでなく格納することで、これを最適化することで、だから、ゲストリストテーブルを参照するのではなく、すべてのチケットの親イベント、会場、アカウントを参照することになります。 これは達成するのは非常に簡単ですが、これは私が冗長なデータを保存し、親を変えることは面倒でエラーが起こりやすいことを意味します。

理想的なソリューション(つまり、冗長データを必要としないものは何でも)ここ

任意の提案ですか?

+1

本当にこれらのテーブルのすべての列を選択する必要がありますか?そうでなければ、どのテーブルを実際に選択する必要がありますか? – ruakh

+0

私はuser_detailテーブルから選択する必要がありますが、私はこの階層トラバーサルを行うために他のものに参加する必要がありますか? –

+0

また、ANSI SQL JOIN構文の学習に少し時間を費やしても、長期的には大きな配当を支払うことになります! – ninesided

答えて

3

ORのパフォーマンスを向上させる最も一般的な方法の1つは、UNION ALLを使用することです。

だから彼らはまた、私は t.guest_listg.evente.venuev.accountはインデックスで覆われていることを願っています

、そうでないとUNION ALL(一つだけの参加で各1)4にクエリを分割しましたか?

+0

本当にここに役立つでしょうか?問題は、チケットごとに下から上に階層をたどる必要があると思います。 –

+0

横断的な問題とは考えないようにしてください。あなたが実際にやっていることは、ベースに基づいています。セットから与えられたレコード。データベースの索引付けが適切であれば、上記のアプローチが非常に迅速であることが期待されます.4つのUNION ALLを一緒に使用すると、検索するのが非常に高速になります。 – ninesided

+0

@Piotr Blasiak:それは確かです。あなたの現在の問題は、現在、条件付き結合が 'OR'によって実装されていることです。 1つのテーブルでも「OR」はあまり最適化できませんが、ジョインで作業するときは地獄になります – zerkms