Mail.ruПочтаМой МирОдноклассникиВКонтактеИгрыЗнакомстваНовостиКалендарьОблакоЗаметкиВсе проекты

Как ускорить select из БД?

Pool Мастер (2486), закрыт 4 года назад
Есть БД (mysql). Там есть 2 таблицы:
users_cities (user_id, city_id)
cities (city_id, name, ..)
У одного пользователя могут быть несколько городов, Пользователей много (больше 1 млн, это всего лишь пример). Моя задача получить иноформацию о городах определенных пользователеи имея список ID.
Пробовал так
$citiesIds = $db->query("SELECT city_id FROM users_cities WHERE user_id IN ( $users )");
$cities = $db->query("SELECT city_id, name FROM cities WHERE city_id in ($citiesIds)");

или 1 запросом:
$cities = $db->query("SELECT T1.city_id as city_id, T1.name FROM cities as T1 WHERE city_id in ( SELECT T2.city_id FROM users_cities as T2 WHERE user_id IN ($users) )");

Время выполнения в обоих случах примерно одинаковое ( 3-4 с ). Индексы полям добавил (без них все печальнее).

Можно все это ускорить? Может структуру менять?
Лучший ответ
А Мудрец (14639) 4 года назад
Попробуй сделать не IN ($users), а создать для $users переменную-таблицу и через join её присоединить.
Во втором запросе два from, это вроде как приводит к декартовому произведению результатов. Там точно всё правильно?

План запроса посмотри, где узкое место. Возможно индексы неправильно заданы

Еще проверь выполнение этих запросов напрямую в субд, а не через php-скрипт. Может в php какие-нибудь настройки не заданы.
PoolМастер (2486) 4 года назад
Проверил select from users_cities через phpmyadmin, все быстро но он добовляет limit. Если поставить limit не 0, 25 - а например 10000, 30 то все медленнее. Напрямую в mysql результаты примерно одинаковые.

Сделал через JOIN (не уверен что имеено как вы имели введу)
SELECT cities.name FROM cities INNER JOIN users_cities using(city_id) WHERE users_cities.user_id IN ($users) - тоже медленно

"... а создать для $users переменную-таблицу и через join её присоединить ..." - пока не пробовал, но попробую (нужно еще прочитать как это делать)
А Мудрец (14639) Лучше всего план запроса посмотреть. В SSMS его можно легко посмотреть, там кнопка "показать план выполнения". Если что, сюда скиньте xml-файл плана.
Остальные ответы
Редис Александрович Оракул (77333) 4 года назад
Попробуй $citiesIds = $db->query("SELECT * FROM users_cities WHERE user_id IN ( $users )");
PoolМастер (2486) 4 года назад
SELECT * - будет быстрее чем SELECT city_id? Почему так?
Александр Искусственный Интеллект (290747) 4 года назад
у свсякой оптимизации есть предел
возможно что ты достиг этого предела
PoolМастер (2486) 4 года назад
Это мало вероятно. Вероятнее я чтото неправельно делал или понял. Или есть вещи о которых не думал.
Похожие вопросы