In關鍵字原理:
SELECT * FROM
user
WHERE id in (SELECT user_id FROM
product
)
in()語句隻會執行一次,它查出
product
表中的所有user_id字段并且緩存起來,之後,檢查
user
表的id是否和
product
表中的user_id相當,如果相等則加入結果期,直到周遊完
user
的所有記錄。
原理:笛卡爾積,周遊外表次數*内表次數
in的查詢過程類似于以下過程:
$result = [];
$users = "SELECT * FROM `user`";
$products = "SELECT user_id FROM `product`";
for($i = 0;$i < $users.length;$i++){
for($j = 0;$j < $products .length;$j++){
// 此過程為記憶體操作,不涉及資料庫查詢。
if($users[$i].id == $products[$j].user_id){
$result[] = $users[$i];
break;
}
}
}
exists關鍵字原理
SELECT * FROM
user
WHERE exists (SELECT * FROM
product
WHERE user.id = product.user_id)
exists語句會執行user.length次,它并不會去緩存exists的結果集,因為這個結果集并不重要,你隻需要傳回真假即可。
原理:外表次數*内表記錄查詢sql
exists的查詢過程類似于以下過程:
$result = [];
$users = "SELECT * FROM `user`";
for($i=0;$i<$users.length;$i++){
if(exists($users[$i].id)){// 執行SELECT * FROM `product` WHERE user.id = product.user_id
$result[] = $users[$i];
}
}
當product表比user表大很多的時候,使用exists是再恰當不過了,它沒有那麼多周遊操作,隻需要再執行一次查詢就行。
但是:user表有10000條記錄,product表有100條記錄,那麼exists()還是執行10000次,還不如使用in()周遊10000*100次,因為
in()是在記憶體裡周遊,而exists()需要查詢資料庫
,我們都知道查詢資料庫所消耗的性能更高,而記憶體比較很快.
結論:exist适合子表比父表資料大的情況,in則相反。使用時,需要正确評估父子表的資料預期增長情況做合适的選擇。