MYSQL中IN與EXISTS的區別
一、總結
一句話總結:
實踐:我之前的mysql真的學的太淺了,這種情況下,依據實踐(做題)才是唯一能把它學好的方式
EXISTS()查詢是將主查詢的結果集放到子查詢中做驗證,根據驗證結果是true或false來決定主查詢數據結果是否得以保存。
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
工作原理:緩存B中查詢出來的id,A表查詢時比較緩存數據,滿足條件的數據加入結果集
以上in()中的查詢只執行一次,它查詢出B中的所有的id並緩存起來,然后檢查A表中查詢出的id在緩存中是否存在,如果存在則將A的查詢數據加入到結果集中,直到遍歷完A表中所有的結果集為止。
2、in做嵌套查詢的話適合什么情況(從AB表的大小分析)?
適合B表數據比A表數據小的情況:b表符合要求的數據在緩存,a中每查詢一次比較一次緩存
因為B表符合要求的數據存在緩存里面,A中的每條數據每查詢一次都要比較整個緩存
3、EXISTS()查詢返回的是什么?
一個布爾值true或flase:它只在乎EXISTS()的查詢中是否有記錄,與具體的結果集無關。
4、EXISTS()查詢的工作原理是什么?
EXISTS()查詢是將主查詢的結果集放到子查詢中做驗證,根據驗證結果是true或false來決定主查詢數據結果是否得以保存。
二、MYSQL中IN與EXISTS的區別
轉自或參考:MYSQL中IN與EXISTS的區別
https://blog.csdn.net/weixin_39539399/article/details/80851817
在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()中的查詢只執行一次,它查詢出B中的所有的id並緩存起來,然后檢查A表中查詢出的id在緩存中是否存在,如果存在則將A的查詢數據加入到結果集中,直到遍歷完A表中所有的結果集為止。
以下用遍歷結果集的方式來分析IN查詢
通過以上程序可以看出,當B表的數據較大時不適合使用in()查詢,因為它會將B表中的數據全部遍歷一次
例如:
1、A表中有100條記錄,B表中有1000條記錄,那么最多可能遍歷100*1000次,效率很差
2、A表中有1000條記錄,B表中有100條記錄,那么最多可遍歷1000*100此,內循環次數減少,效率大大提升
結論:IN()查詢適合B表數據比A表數據小的情況,IN()查詢是從緩存中取數據
2、EXISTS查詢分析
語法:SELECT 字段 FROM table WHERE EXISTS(subquery);
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()查詢會執行SELECT * FROM A查詢,執行A.length次,並不會將EXISTS()查詢結果結果進行緩存,因為EXISTS()查詢返回一個布爾值true或flase,它只在乎EXISTS()的查詢中是否有記錄,與具體的結果集無關。
EXISTS()查詢是將主查詢的結果集放到子查詢中做驗證,根據驗證結果是true或false來決定主查詢數據結果是否得以保存。
以下用遍歷結果集的方式來分析EXISTS查詢
從以上程序可以看出:
當B表的數據比A表的數據大時適合使用EXISTS()查詢,因為它不用遍歷B操作,只執行一次查詢就OK了
例如:
1、A表有100條記錄,B表有1000條記錄,那么EXISTS()會執行100次去判斷A表中的id是否與B表中的id相等.因為它只執行A.length次,可見B表數據越多,越適合EXISTS()發揮效果.
2、A表有10000條記錄,B表有100條記錄,那么EXISTS()還是執行10000次,此時不如使用in()遍歷10000*100次,因為IN()是在內存里遍歷數據進行比較,而EXISTS()需要查詢數據庫,我們都知道查詢數據庫所消耗的性能更高,而內存比較很快.
3、結論:
exists()適合B表比A表數據大的情況
當A表數據與B表數據一樣大時,in與exists效率差不多,可任選一個使用