The following inquiries / inquiries are received by the cities visited by the user, they receive the places where the user visited; and returns places in cities where the user has not been.
// I get the city_id and object_id. Each vote has the place_id and its city_id. SELECT DISTINCT city_id as city_id, object_id as object_id FROM vote WHERE object_model = 'Place' AND user_id = 20 ORDER BY created_at desc // I build an array with city_ids and another with object_ids $city_ids = array(...); $place_ids = array(...);
I get places where the user was not in the cities where he was - 1 second
SELECT id, title FROM place WHERE city_id IN ($city_ids) AND id NOT IN ($place_ids) ORDER BY points desc LIMIT 0,20
EXPLAIN SQL
select_type table type possible_keys key key_len ref ows Extra ----------------------------------------------------------------------------------------------------------- SIMPLE p range PRIMARY,city_id_index city_id_index 9 NULL 33583 Using where; Using filesort
Another attempt to optimize is to make one request using LEFT JOIN / IS NULL and a subquery, but it takes much longer (30 + seconds)
SELECT id, title FROM place AS p LEFT JOIN vote v ON v.object_id = p.id AND v.object_model = 'Place' AND v.user_id = 20 WHERE p.city_id IN (SELECT city_id FROM vote WHERE user_id = 20 AND city_id != 0) AND v.id is null ORDER BY p.points desc LIMIT 0, 20
How will you make a request / requests, thinking that we can have an array of 500 cities and 1000 places for each user? What is the best alternative to where and where NOT IN when there are many identifiers?
fesja source share