Есть ли более эффективный способ сделать это? Я продолжаю думать, что я что-то упускаю. Спасибо
SELECT DISTINCT eventId
FROM event_tags_map
WHERE tagId in (
SELECT tagId FROM event_tags_map WHERE eventId=114778
) ORDER BY RAND() LIMIT 5;
Я дважды попадаю в один и тот же стол, и мне интересно, смогу ли я получить те же результаты быстрее.
Структура таблицы:
mysql> describe event_tags_map;
+---------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+------------------+------+-----+---------+-------+
| eventId | int(10) unsigned | NO | PRI | NULL | |
| tagId | int(10) unsigned | NO | PRI | NULL | |
+---------+------------------+------+-----+---------+-------+
Индексы:
mysql> show index from event_tags_map;
+----------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+----------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| event_tags_map | 0 | PRIMARY | 1 | eventId | A | 302032 | NULL | NULL | | BTREE | | |
| event_tags_map | 0 | PRIMARY | 2 | tagId | A | 604065 | NULL | NULL | | BTREE | | |
+----------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
2 rows in set (0.02 sec)






Похоже, вам нужно будет дважды обратиться к исходной таблице, так или иначе.
Я бы рекомендовал не использовать условие IN, которое не очень масштабируемо и имеет различные нелогичные действия.
Мой первый вариант использования коррелированного подзапроса с условием EXISTS. Обычно это самый эффективный способ проверить, что что-то существует...
SELECT DISTINCT eventId
FROM event_tags_map m
WHERE EXISTS (
SELECT 1 FROM event_tags_map m1 WHERE m1.eventId = 114778 AND m1.tagId = m.tagId
)
ORDER BY RAND() LIMIT 5;
Альтернативный вариант — использовать self-INNER JOIN:
SELECT DISTINCT eventId
FROM event_tags_map m
INNER JOIN event_tags_map m1 ON m1.eventId = 114778 AND m1.tagId = m.tagId
ORDER BY RAND() LIMIT 5;
Оба решения должны иметь возможность использовать составной индекс для event_tags_map(eventId, tagId).