如果查询的两个表中一个是小表,一个是大表,IN适合于外表大而内表小的情况,EXISTS适合于外表小而内表大的情况。
文章目录1. 为什么 IN 适合“外大内小”2. 为什么 EXISTS 适合“外小内大”3. 形象类比找钥匙4. 总结与口诀这个问题问到了点子上这其实是数据库优化中非常经典的**“小表驱动大表”**原则。理解这个问题的核心在于看谁先执行以及循环是怎么嵌套的。1. 为什么IN适合“外大内小”当执行A IN (SELECT id FROM B)时数据库通常的操作逻辑是先执行子查询内表 B并把结果存放在一个内存临时表中通常是 Hash 表。遍历外表 A拿着 A 的每一行去刚才那个内存表里找是否存在。为什么内表小更好如果内表 B 很小生成的临时表就小占用的内存少。对于外表 A 的每一行去内存 Hash 表里匹配的速度极快接近O ( 1 ) O(1)O(1)。哪怕 A 有 100 万行也只是做了 100 万次内存查询不需要频繁去磁盘扫 B 表。2. 为什么EXISTS适合“外小内大”当执行A WHERE EXISTS (SELECT 1 FROM B WHERE B.id A.id)时逻辑变了先遍历外表 A外表驱动内表。对于 A 的每一行都跑进子查询 B 里探测一下有没有符合条件的记录。为什么外表小更好如果外表 A 很小比如只有 10 行那么子查询 B 也就只需要被触发 10 次。关键点虽然 B 表很大比如 1000 万行但如果 B 表的关联字段如id有索引那么这 10 次探测都是极快的索引寻址。短路特性EXISTS只要在 B 表里找到第一条匹配的记录就会立即停止并返回 True它不需要把 B 表的所有数据都查出来。3. 形象类比找钥匙假设你要在“一堆盒子”里找“一把匹配的钥匙”。IN方式内表小你先把所有的钥匙内表拿在手里。然后去走过每一个盒子外表拿手里的钥匙对一下。如果你只有 2 把钥匙即便有 1000 个盒子你走一圈也就很快对完了。EXISTS方式外表小你只有 2 个盒子外表。你拿着这两个盒子跑去钥匙仓库内表里问管理员“你有配这盒子的钥匙吗” 仓库虽然有几万把钥匙但管理员有索引目录瞬间就能告诉你有没有。4. 总结与口诀这个结论其实是基于总执行成本 外表扫描次数 外表行数 × 子查询查询成本得出的。语法驱动顺序优势场景记忆口诀IN先内后外外大内小内表小内存存得下IN更好。EXISTS先外后内外小内大外表小查询次数少EXISTS稳。