2017-05-03 3 views
0

私は両方ともにvenue_idという2つの大きなテーブルを持っています。それは2つの独立した値であるため、外部キーではありません。彼らは、次のとおりです。2つのテーブルにまたがるWHEREを使用したMySQL経由の大規模テーブルクエリ

table: activity_retail 
columns: activity_id, venue_id, created_at 
indexes: activity_id (PRIMARY), (activity_id, venue_id) INDEX 


table: activity 
columns: activity_id, item_id, venue_id, created_at 
indexes: activity_id (PRIMARY), (created_at) INDEX 

私はvenue_idが各テーブルにXに等しいすべての活動に、それらの両方の間でクエリを実行したいと思います。だから私はどうなる:

SELECT * from activity 
    LEFT JOIN activity_retail on activity_retail.activity_id = activity.activity_id 
    WHERE activity_retail.venue_id = X or activity.venue_id = X 
ORDER BY activity_retail.created_at desc LIMIT 0, 25 

私もページネーションのために、このクエリを実行する必要がある場合があります

​​

状況が存在しない可能性がactivity_idactivity_retailで、それはオプションのフィールドですので、私ができます」内部結合を行うには、左結合でなければなりません。ここで

EXPLAIN次のとおりです。

1 PRIMARY activity index ix_ivi_created created_at 8 NULL 25 Using where 
1 PRIMARY activity_retail eq_ref PRIMARY PRIMARY 4 activity.activity_id 1 

それは(EXPLAINに応じて)小さなクエリですが、それは実行に非常に長い時間がかかり、EXTRASエリアには何も使用しません。

これを正しく動作させる方法については、 ORステートメントを使用して2つのテーブルの条件を基本的にアドバイスしてください。 ANDは本当にうまく機能しますが、ここにはORが必要です。

+0

「venue_idが各テーブルにXに等しい」あなたは私たちがあなたのインデックスを見ることができますか?また – ghenghy

+0

テーブルの上に記述を提供することができ、あなたが言うが、あなたのどちらのテーブルでもvenue_idとXが同じではない場合 – ghenghy

+0

サンプルデータと目的の結果も参考になります – ghenghy

答えて

0

あなたは左ジョインに非常に近いようです。ただし、小売表のWHERE句に条件を移すとすぐに、内部結合が強制されます。以下を試してください...

SELECT 
     A.*, 
     AR.* 
    from 
     activity A 
     LEFT JOIN activity_retail AR 
      on A.activity_id = AR.activity_id 
      AND AR.Venue_ID = X 
    WHERE 
      A.Venue_ID = X 
     OR NOT AR.Activity_ID IS NULL 
    ORDER BY 
     AR.created_at desc 
    LIMIT 
     0, 25 

通知「AR.Venue_ID = X」をJOIN句に移動しました。この方法では、セカンダリテーブルに "X"がある場合にのみ一致します。それ以外の場合は常にNULLになります。

ここで、where句はVenue_IDまたはAR_ActivityIDのアクティビティテーブル(常にレコードをテストする)をテストしません。つまり、適切な会場のテーブル内のレコードを見つけたので、DOESは結果セット。

うまくいけば、これはあなたが探しているものを行います。

+0

悲しいことに、これは機能しません。また、インデックスを正しく使用すると、フルテーブルスキャンとなります。 – gregavola

関連する問題