首先理解mysql中sql語句如果有 exist和in 是怎麼去執行的
先給個結論後面再去慢慢解釋:
exist適合 子查詢中表資料大於外查詢表中資料的業務場景
in:適合外部表資料大於子查詢的表資料的業務場景
in 和 exists的區別: 如果子查詢得出的結果集記錄較少,主查詢中的表較大且又有索引時應該用in, 反之如果外層的主查詢記錄較少,子查詢中的表大,又有索引時使用exists。其實我們區分in和exists主要是造成了驅動順序的改變(這是效能變化的關鍵),如果是exists,那麼以外層表為驅動表,先被訪問,如果是in,那麼先執行子查詢,所以我們會以驅動表的快速返回為目標,那麼就會考慮到索引及結果集的關係了 ,另外in時不對null進行處理。
in 是把外表和內錶作hash 連線,而exists是對外表作loop迴圈,每次loop迴圈再對內表進行查詢。一直以來認為exists比in效率高的說法是不準確的
兩者在sql中執行的差別:
exist: 先執行外部查詢語句,然後在執行子查詢,子查詢中它每次都會去執行資料庫的查詢,執行次數等於外查詢的資料數量。查詢資料庫比較頻繁(記住這點),如果b表再id上加了索引也會走索引
select * from a where exist(select 1 from b.a_id=a.id);
//外部查詢
object out=;
listresult=new arraylist();
for(int i=0;i//子查詢(內查詢)
//1 去查詢資料庫
// 2 判斷外部資料的值執行第一步是是否能查到資料,返回 ture或者false
// 3 如果第二部為true
if(exiset(out[i].id));
object in=;
listresult=new arraylist();
for(int i =0; i<>out.size();i++)
for (int j = 0 ; jif(out[i].id=in[j]){
result.add(out[i]));
這個的操作主要是在記憶體進行,不會進行資料庫的多次查詢。
------------------後補----------------------
發現個問題: 其實使用in是 a表並不會走索引,索引覺得不管時a,b表哪個表資料量大用 in還是exist都覺得無所謂,反正子查詢加了索引會走索引,exist相反更加耗時,因為會多次查詢資料庫, 這一結論後面再論證
堆區和棧區的區別
一 預備知識 程式的記憶體分配 乙個由c c 編譯的程式占用的記憶體分為以下幾個部分 1 棧區 stack 由編譯器自動分配釋放 存放函式的引數值,區域性變數的值等。其操作方式類似於資料結構中的棧。2 堆區 heap 一般由程式設計師分配釋放,若程式設計師不釋放,程式結束時可能由os 注意它與資料結...
棧區和堆區的區別
一直以來總是對這個問題的認識比較朦朧,我相信很多朋友也是這樣的,總是聽到記憶體一會在棧上分配,一會又在堆上分配,那麼它們之間到底是怎麼的區別呢?為了說明這個問題,我們先來看一下記憶體內部的組織情況 從上圖可知,程式占用的記憶體被分了以下幾部分 1 棧區 stack 由編譯器自動分配釋放 存放函式的引...
棧區和堆區的區別
1 棧區 stack 由編譯器自動分配釋放 存放函式的引數值,區域性變數的值等,記憶體的分配是連續的,類似於平時我們所說的棧,如果還不清楚,那麼就把它想成陣列,它的記憶體分配是連續分配的,即,所分配的記憶體是在一塊連續的記憶體區域內 當我們宣告變數時,那麼編譯器會自動接著當前棧區的結尾來分配記憶體。...