一般来说数据库查询最好不要用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.先进行内部查询,然后再进行外部查询
如:
关联子查询: 1. 外部查询得到的每天记录传入到内部查询; 2.内部查询基于外部查询传入的值; 3.内部查询从其结果中把值传回到外部查询,外部查询使用这些值来完成其处理。
外部查询返回较少记录时,关联子查询比嵌套子查询效果高;
内部查询返回较少记录时,嵌套子查询比关联子查询效果高.
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要快。