sql查询--join与子查询对比

一般来说数据库查询最好不要用join查询,因为比较慢,但是与子查询相比,join的查询效率还是比子查询高的,个人建议,不要用子查询!

原因是从网上找到的,可以参考:因为使用子查询时,数据库还要建一张临时表,所以效率才会比左连接来得慢(刚开始还以为没准回和索引有关系,事实证明我错了)

SQL中查询的一些对比情况总结:

select xxx

 from A

 where xx = (select xx from B where .......);


情况1:对于外部查询的每行,子查询返回的值都一样(即select xx from B where .......的结果值都相同时)

     优先采用的方法:预查询 先将执行子查询,然后用变量存储查询结果,再用这个变量查询“外部”的每行

      String str ="";//定义一个变量,具体类型根据需求而定

      //执行select xx from B where .......查询

     //将查询结果存放到定义的变量str中

     //根据str动态拼写外部查询SQL   

情况2:两个表都相对较小(比如不超过10000条记录)

     优先采用的方法:子查询(具体原因不清楚,但是运行了几次确实如此,可能查找比连接系统开销小吧)

情况3:根据所有条件,匹配只会返回一个值

优先采用的方法:子查询(具体原因不清楚,但是运行了几次确实如此,可能查找比连接系统开销小吧)

情况4:根据所有条件,匹配只会返回很少的值,在查找列上没有索引

优先采用的方法:子查询(单个查找或者少量查找的系统开销通常比散列连接的系统开销小)

情况5:查找表相对较小,但是基表很大

       优先采用的方法顺序:嵌套子查询,其次是连接,最后是关联子查询

情况6:关联子查询和连接

优先采用的方法顺序:连接  关联子查询将在内部创建嵌套循环,有可能造成很大开销。大部分情况下,关联子查询比游标更快,但是比其他可选方法都慢

情况7:派生表和其他任何可选方法

派生表要慎用,因为它运行一次之后,驻留在内存之中,在结果集较大而且缺少索引的时候他可能很快,也可能很慢,视情况而定

情况8 :exist和其他任何方法

优先采用exist。对于同样的匹配exist不需要多次查找




嵌套子查询和关联子查询

嵌套子查询: 1. 内部查询只处理一次; 2. 与null比较,总得到null 3.先进行内部查询,然后再进行外部查询

如:

[sql]  view plain  copy
  1. SELECT *  
  2.   FROM emp A  
  3.  WHERE A.sal < (SELECT AVG(sal) FROM emp B WHERE A.deptno = B.deptno); 

关联子查询: 1. 外部查询得到的每天记录传入到内部查询; 2.内部查询基于外部查询传入的值; 3.内部查询从其结果中把值传回到外部查询,外部查询使用这些值来完成其处理。

[sql]  view plain  copy
  1. SELECT A.*  
  2.   FROM emp A, (SELECT deptno, AVG(sal) sal FROM emp GROUP BY deptno) B  
  3.  WHERE A.deptno = B.deptno  
  4.    AND A.sal < B.sal;  

  外部查询返回较少记录时,关联子查询比嵌套子查询效果高;

  内部查询返回较少记录时,嵌套子查询比关联子查询效果高.

in和exists

select * from A where cc in (select cc from B)

  如果表A较大,那么in比exists的效率要高(可以用到B表上cc列的索引).

select * from A where exists (select cc from B where cc=A.cc)

  如果表A较小,那么exists比in的效率要高(可以用到A表上cc列的索引)


not in 和not exists

如果查询语句使用了not in 那么内外表都进行全表扫描,没有用到索引;
  而not extsts 的子查询依然能用到表上的索引。
  所以无论那个表大,用not exists都比not in要快。

你可能感兴趣的:(mysql)