两种方法,自测都好使,60s的执行时间缩短到了2s左右
我遇到的问题大概是这样
比如说我写了个sql:
select * from student where name in('lilei','hanmeimei');
这就是在student表查名字是lilei hanmeimei的sql,假如说现在这个sql执行很慢,然后我发现只要把这个in子句去掉之后就变得很快,那这个时候肯定是要想办法替换掉这个in子句。
第一种:values子句
你可以按照下边这种写法,先把lilei hanmeimei这样的匹配元素模拟成一张表放在那,然后再用连接查询的方式来查询,这样会很快:
with params(name) as (
values ('lilei'),('hanmeimei')
)
这就类似于你又搞出来一张表,里边只有lilei hanmeimei这俩数据,然后你原本的sql就可以改成这样:
select * from student s right join params p on s.name=p.name
第二种:exists函数
用这个函数的写法是这样的:
select * from student exists (select t2.* from student from student t2 where student.name=t2.name and t2.name in('lilei','hanmeimei'))
这种写法虽然没有替换掉in子句,但是他的原理也还是把通过in子句限制查询条件改成了连接查询,因为即使在子查询内部使用了in,单表的情况下也不会造成性能丢失,在子查询内就把单表内数据通过in子句维护出来,在外层就不会出现因为联表查询或者其他情况造成索引失效等查询速率很慢的情况了。