使用MySql查询数据时,一直搞不清楚in和exists两者到底有什么区别,今天总算搞清楚了。
大概规则如下:
当B表的数据集小于A表数据集时,用in优于exists。
selectidfromAwhereidin(selectidfromB)
当A表的数据集小于B表的数据集时,用exists优于in。
selectidfromAwhereidin(selectidfromB);
可以这么理解:in后面跟的是小表,exists后面跟的是大表
select*fromAwhereidin(selectidfromB)也可以写成selectidfromBbleftjoinselectidfromAawherea.id=b.id
小表驱动大表
为什么会这样呢,这里我们需要了解MySql的小表驱动大表。
我们在编写程序时,时常遇到循环嵌套的,最常见的莫过于两个for嵌套
例如
for(inti=0;i10;i++){for(intj=0;j;j++){}}
如果小的循环在外层,对于数据库连接来说就只连接10次,进行0次操作。
如果在外,则需要进行次数据库连接,这样就相当浪费资源了。
MySql的join实现原理,以驱动表的数据为基础,“嵌套循环”去被驱动表匹配记录,例如:
select*fromajoinbona.id=b.id
假设a表000数据,b表数据,这里有两个过程,b表数据最少,查询引擎优化选择b为驱动表,循环b表的条数据,跟a表的000数据去匹配,这个匹配的过程是B+树的查找过程,比循环取数要快的多。
需要注意的是a表字段id和b表字段id都要建立索引。
总结:
小表驱动大表,in后面跟的是小表,exists后面跟的是大表。
由于笔者知识及水平有限,文中错漏之处在所难免,如有不足之处,欢迎交流。