在mysql优化中,遵循小表驱动大表的原则
1. in查询
SELECT * FROM A WHERE id IN (SELECT id FROM B);
等价于:
1、SELECT id FROM B ----->先执行in中的查询
2、SELECT * FROM A WHERE A.id = B.id
in表示先执行内表,将内表查询数据存储起来,在查询外表,并查询A表的id是是否存在于缓存中,如果存在则返回到结果集中
举例: (A为外表 B为内表)
- A表中有100条记录,B表中有1000条记录,那么最多可能遍历100 * 1000次,效率很差
- A表中有1000条记录,B表中有100条记录,那么最多可遍历1000 * 100次,内循环次数减少,效率大大提升
2. exists
SELECT * FROM a WHERE EXISTS(SELECT 1 FROM b WHERE B.id = A.id);
以上查询等价于:
1、SELECT * FROM A;
2、SELECT I FROM B WHERE B.id = A.id;
exists表示先对外表进行查询,再将查询结果与内表查询结果进行比对,没有缓存,exists返回true 或false,if true则将结果放入结果集中
举例
- A表有100条记录,B表有1000条记录,那么EXISTS()会执行100次去判断A表中的id是否与B表中的id相等.因为它只执行A.length次,可见B表数据越多,越适合EXISTS()发挥效果.
- A表有10000条记录,B表有100条记录,那么EXISTS()还是执行10000次,此时不如使用in()遍历10000*100次,因为IN()是在内存里遍历数据进行比较,而EXISTS()需要查询数据库,我们都知道查询数据库所消耗的性能更高,而内存比较很快.
结论:
内表和外表如果数据差别不大,则性能相同
如果内表数据量少,则用in
如果外表数据量少,则用exists