数据库有一个学生表t_student有两个字段 id, name
我想找出name相同的所有数据的id,并根据name排序,好做对比。如
id | name |
---|---|
1 | 张三 |
2 | 李四 |
3 | 张三 |
4 | 王五 |
5 | 王五 |
我想找出的数据是
id | name |
---|---|
1 | 张三 |
3 | 张三 |
4 | 王五 |
5 | 王五 |
写下的sql如下
select id, name from t_student where name in (select name from t_student where name is not null group by name having count(*) > 1) order by name;
虽然能得到想要的数据,但是查询的速度很慢。要6s左右。
后面发现这种写法,在数据量大时,查询时间能缩短10倍以上。由6s -> 0.6s。而区别是多了个中间表。
select id, name from t_student where name in (select t.name from (select name from t_student where name is not null group by name having count(*) > 1) as t) order by name;
为了判断是否是中间表的创建导致的查询效率的提升,我换了一种写法
select ts.id, ts.name from t_student ts inner join (select t.name from t_student where name is not null group by name having count(*) > 1) as t on ts.name = t.name order by name;
通过创建中间表然后join的方式,还是很快,大概也是0.6s。
我想知道为什么这样,创建中间表为什么会比不创建要快这么多
MySQL子查询(IN)碰到的问题,深入分析
不加 中间表的 IN
select A from B
的每行结果 都会执行一次查下select C FROM D
加了中间表的 IN
只执行一次
select C FROM D