SELECT `bio_community_events`.`id`,
`bio_community_events`.`begin_on`,
`bio_community_events`.`name`
FROM `bio_community_events`
JOIN `bio_contacts`
ON (`bio_contacts`.`contact_id` = `bio_community_events`.`user_id`)
WHERE `bio_contacts`.`user_id` = '33'
UNION ALL --- or UNION if this gives you
--- duplicate row
SELECT `bio_community_events`.`id`,
`bio_community_events`.`begin_on`,
`bio_community_events`.`name`
FROM `bio_community_events`
JOIN `bio_contacts`
ON (`bio_contacts`.`user_id` = `bio_community_events`.`user_id`)
WHERE `bio_contacts`.`contact_id` = '33'
или как это:
SELECT `bio_community_events`.`id`,
`bio_community_events`.`begin_on`,
`bio_community_events`.`name`
FROM `bio_community_events`
JOIN
( SELECT `bio_contacts`.`contact_id` AS id
FROM `bio_contacts`
WHERE `bio_contacts`.`user_id` = '33'
UNION ALL
SELECT `bio_contacts`.`user_id` AS id
FROM `bio_contacts`
WHERE `bio_contacts`.`contact_id` = '33'
) AS un
ON ( un.id = `bio_community_events`.`user_id`)
Чтобы установить предел для всех возвращаемых строк в примере # 1, используйте:
( SELECT ... )
UNION ALL
( SELECT ... )
ORDER BY ? --- optional
LIMIT x ;
Использование ORDER BY
тамможет быть довольно дорогостоящим в таком запросе.Вы также можете иметь этот (другой) запрос, который может использовать индексы:
( SELECT ...
ORDER BY ?
LIMIT a
)
UNION ALL
( SELECT ...
ORDER BY ?
LIMIT b
)
LIMIT x ; --- with or without this LIMIT
Другой способ решения исходной проблемы - использовать EXISTS
:
SELECT `bio_community_events`.`id`,
`bio_community_events`.`begin_on`,
`bio_community_events`.`name`
FROM `bio_community_events`
WHERE EXISTS
( SELECT *
FROM `bio_contacts`
WHERE `bio_contacts`.`user_id` = '33'
AND `bio_contacts`.`contact_id` = `bio_community_events`.`user_id`
)
OR EXISTS
( SELECT *
FROM `bio_contacts`
WHERE `bio_contacts`.`contact_id` = '33'
AND `bio_contacts`.`user_id` = `bio_community_events`.`user_id`
)
или:
SELECT `bio_community_events`.`id`,
`bio_community_events`.`begin_on`,
`bio_community_events`.`name`
FROM `bio_community_events`
WHERE EXISTS
( SELECT *
FROM `bio_contacts`
WHERE ( `bio_contacts`.`user_id` = '33'
AND `bio_contacts`.`contact_id` = `bio_community_events`.`user_id` )
OR ( `bio_contacts`.`contact_id` = '33'
AND `bio_contacts`.`user_id` = `bio_community_events`.`user_id` )
)
Если ваш план состоит в том, чтобы найти наиболее эффективный запрос, попробуйте все, что работает правильно (с помощью IN, с помощью UNION, с помощью EXISTS) - добавьте ORDER BY
, который вы хотите вне курса - ипроверка их скорости и планов выполнения.
Я бы, по крайней мере, имел:
- в таблице
bio_community_events
- индекс на
user_id
- индекс поля (полей), используемый для
ORDER BY
и
- в таблице
bio_contacts
, два составных индекса - в
(contact_id, user_id)
и - в
(user_id, contact_id)
И еще один вопрос, если вы не можете запустить его менее чем за Xмиллисекунды (X решил ваш босс:)