Я думаю, что пункты IN
просто идеально подходят для работы. (Можно сделать то же самое с EXISTS
, но это, конечно, должно привести к тому же плану выполнения.)
Укажите следующий индекс, чтобы быстро получить города для провинции:
create idx_province_city on t_map_city (provinceid, city_id);
Если это все еще слишком медленно, тогда мы должны прибегнуть к хитрости. Я считаю, что присоединение вместо простых IN
или EXISTS
предложений может быть таким трюком. (И это прискорбный трюк, потому что СУБД должна легко увидеть, что два запроса делают одно и то же и, следовательно, имеют один и тот же план выполнения).
Еще один трюк - поиск кортежей:
create index idx_city_tuple on t_link (star_city_id, end_city_id);
select *
from t_link a
where (star_city_id, end_city_id) in
(
select a.cityId, b.cityId
from (select cityId from t_map_city where provinceid = 350) a
cross join (select cityId from t_map_city where provinceid = 350) b
);
Мне самому не нравится этот подход, но я бы все-таки применил его, если бы остро нуждался в повышении моего запроса. (А потом еще посмотреть, действительно ли это быстрее.)