Объединяет на одном столе - PullRequest
0 голосов
/ 04 марта 2019

Есть ли более эффективный способ сделать это?Я продолжаю думать, что что-то упустил.Спасибо

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)

1 Ответ

0 голосов
/ 04 марта 2019

Похоже, вам нужно будет обратиться к исходной таблице дважды, так или иначе.

Я бы порекомендовал не использовать условие 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).

...