Таблицы соединения MySQL с несколькими повторяющимися значениями в столбцах соединения
Ограничения
- Таблицы не нормализованы
- Невозможно использовать подзапрос
таблицы
Имя: Места
+-----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | 0 | auto_increment |
| zip_code | varchar(12) | NO | | | |
| city | varchar(64) | NO | MUL | | |
| county | varchar(64) | NO | MUL | | |
| state | varchar(64) | NO | MUL | | |
| info | varchar(99) | NO | | | |
+-----------+-------------+------+-----+---------+----------------+
Имя: Адреса
+------------------+---------------+------+-----+-------+-----------+
| Field | Type | Null | Key | Default | Extra |
+------------------+---------------+------+-----+-----------+-------+
| id | int(11) | NO | PRI | 0 | |
| address_one | varchar(255) | NO | | | |
| address_two | varchar(255) | NO | | | |
| city | varchar(30) | NO | MUL | | |
| state | varchar(25) | NO | MUL | | |
| zip_code | varchar(7) | NO | MUL | NULL | |
| country_code | char(2) | YES | | | |
+------------------+---------------+------+-----+-----------+-------+
Эта проблема
- Расположение таблиц и адресов будет иметь
state
дублируется во многих рядах. - ТаблицаLocations содержит около 100 тыс. Строк, а таблица адресов - около 1 млн. Строк.
Вопрос
Мне нужно получить уникальный список states
с их info
из таблицы Locations, где есть хотя бы один адрес в таблице адресов для любого соответствующего state
,
Любое присоединение, которое у меня есть, без использования подзапросов, в конечном итоге будет длиться вечно.
Какой запрос удовлетворит ограничения?
2 ответа
Это миф, что подзапросы являются проблемой производительности. Иногда они есть; иногда это не так. Нет такого простого правила.
В вашем случае я мог бы предложить:
select l.*
from (select distinct state, info
from locations l
) l
where exists (select 1
from addresses a
where a.state = l.state
);
Для производительности вы хотите индексы на locations(state, info)
а также addresses(state)
,
Есть два подзапроса, но с соответствующими индексами, это может быть просто самый быстрый способ выразить эту логику.
Вы можете использовать:
SELECT state, info FROM locations LEFT JOIN addresses USING (state) WHERE address_one IS NOT NULL GROUP BY state;
Этот запрос не использует подзапрос.