Как оптимизировать SQL, который содержит такое же предложение "в"? - PullRequest
0 голосов
/ 08 апреля 2019
select *
from t_link a
WHERE a.STAR_CITY_ID in (select cityId from `t_map_city` t
                         WHERE t.PROVINCEID = 350) and
      a.END_CITY_ID in (select cityId from `t_map_city` t
                        WHERE t.PROVINCEID = 350);

Это мой sql.Как я могу оптимизировать его для повышения эффективности?

select * from `t_ne$link` a 
JOIN (select cityId from `t_map_city` t WHERE t.PROVINCEID=350) tb1 
  on (a.END_CITY_ID in (tb1.cityId) and a.STAR_CITY_ID in (tb1.cityId)); 

Я изменил его на это, но он не работает.

Ответы [ 3 ]

0 голосов
/ 08 апреля 2019

Ну, использование EXISTS также может помочь:

select *
from t_link a
WHERE exists(select 1 from `t_map_city`
             where cityId = a.start_city_id and provinceId = 350)
and exists(select 1 from `t_map_city`
             where cityId = a.end_city_id and provinceId = 350)
0 голосов
/ 08 апреля 2019

Я думаю, что пункты 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
);

Мне самому не нравится этот подход, но я бы все-таки применил его, если бы остро нуждался в повышении моего запроса. (А потом еще посмотреть, действительно ли это быстрее.)

0 голосов
/ 08 апреля 2019

Я бы порекомендовал использовать явные объединения:

select l.*
from t_link l join
     t_map_city mcs
     on l.start_city_id = mcs.cityId and
        mcs.provinceid = 350 join
     t_map_city mce
     on l.start_city_id = mce.cityId and
        mce.provinceid = 350;

Для производительности вам, вероятно, нужен индекс для t_map_city(cityId, provinceId).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...