mysql exist和in的區別

2021-09-07 16:21:01 字數 1317 閱讀 8537

首先理解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 由編譯器自動分配釋放 存放函式的引數值,區域性變數的值等,記憶體的分配是連續的,類似於平時我們所說的棧,如果還不清楚,那麼就把它想成陣列,它的記憶體分配是連續分配的,即,所分配的記憶體是在一塊連續的記憶體區域內 當我們宣告變數時,那麼編譯器會自動接著當前棧區的結尾來分配記憶體。...