我有两个大表,两个都有一个venue_id
。它不是外键,因为它们是两个独立的值。它们如下:
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
我也可能需要对分页进行此查询:
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 and activity.activity_id > Y
ORDER BY activity_retail.created_at desc LIMIT 0, 25
情况是activity_id
中的activity_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
区域中的任何内容。
有关如何使其正常工作的任何建议 - 基本上WHERE
条件跨两个表OR
语句? AND
效果很好,但我们需要OR
。
答案 0 :(得分: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子句。这样它只会匹配IF辅助表具有" X"否则它将始终为空。
现在,where子句测试Venue_ID的活动表(总是测试记录)或者AR_ActivityID是非空的(这意味着它找到了具有适当位置的表中的记录,因此存在被引入结果的DOES集。
希望这能满足您的需求。