WHERE x IN ()
идентичен от INNER JOIN
до SELECT DISTINCT
подзапроса, и, как правило, соединение с подзапросом будет работать лучше, если оптимизатор не превратит IN
в JOIN
- который он должен:
SELECT i.*
FROM i
INNER JOIN (
SELECT DISTINCT id
FROM w
WHERE w.status = 'active'
) AS wish
ON i.id = wish.id
INNER JOIN r
ON i.id = r.id
WHERE r.member_id = 1 && r.status = 'active'
ORDER BY wish.id DESC
LIMIT 0,50
Что, вероятно, будет эквивалентно этому, если вам не нужно DISTINCT
:
SELECT i.*
FROM i
INNER JOIN w
ON w.status = 'active'
AND i.id = wish.id
INNER JOIN r
ON i.id = r.id
AND r.member_id = 1 && r.status = 'active'
ORDER BY i.id DESC
LIMIT 0,50
Пожалуйста, опубликуйте свою схему.
Если вы используете желание как флаг существования, попробуйте:
SELECT i.*, CASE WHEN w.id IS NOT NULL THEN 1 ELSE 0 END AS wish
FROM i
INNER JOIN r
ON i.id = r.id
AND r.member_id = 1 && r.status = 'active'
LEFT JOIN w
ON w.status = 'active'
AND i.id = w.id
ORDER BY wish DESC
LIMIT 0,50
Вы можете использовать ту же технику с подзапросом от LEFT JOIN
до SELECT DISTINCT
. Я предполагаю, что вы не указываете w.member_id
, потому что хотите знать, есть ли у кого-либо из них? В этом случае обязательно используйте SELECT DISTINCT
. Вы должны иметь индекс с id
в качестве первого столбца на w
, чтобы это можно было выполнить:
SELECT i.*, CASE WHEN w.id IS NOT NULL THEN 1 ELSE 0 END AS wish
FROM i
INNER JOIN r
ON i.id = r.id
AND r.member_id = 1 && r.status = 'active'
LEFT JOIN (
SELECT DISTINCT w.id
FROM w
WHERE w.status = 'active'
) AS w
ON i.id = w.id
ORDER BY wish DESC
LIMIT 0,50