如何优化包含相同“ in”语句的sql?

时间:2019-04-08 08:32:41

标签: mysql sql

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 :(得分:0)

我建议使用显式联接:

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)上建立索引。

答案 1 :(得分:0)

好吧,使用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)

答案 2 :(得分:0)

我认为IN子句非常适合这份工作。 (一个人可以对EXISTS做同样的事情,但这当然会导致相同的执行计划。)

提供以下索引可以快速获取某省的城市:

create idx_province_city on t_map_city (provinceid, city_id);

如果这仍然太慢,那么我们必须采取一种技巧。我认为加入而不是简单的INEXISTS子句是一个技巧。 (这是一个可悲的窍门,因为DBMS应该很容易地看到两个查询在做相同的事情,因此提出了相同的执行计划。)

另一个技巧是查找元组:

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
);

我本人不喜欢这种方法,但是如果我迫切需要提高查询量,还是可以使用它。 (然后还有待观察这是否真的更快。)