子查詢就是查詢中又嵌套的查詢,錶鏈接均可以用子查詢,但不是全部子查詢都能用錶鏈接替換,子查詢比較靈活,方便,形式多樣,適合用於做爲查詢的篩選條件,而錶鏈接更適合與查看多表的數據。html
子查詢不必定須要兩個表有關聯字段,而鏈接查詢必須有字段關聯(所謂的主外鍵關係)mysql
- 表關聯的效率要高於子查詢,由於子查詢走的是笛卡爾積
- 表關聯可能有多條記錄,子查詢只有一條記錄,若是須要惟一的列,最好走子查詢
對於數據量多的確定是用鏈接查詢快些,緣由:由於子查詢會屢次遍歷全部的數據(視你的子查詢的層次而定),而鏈接查詢只會遍歷一次。git
可是數據量少的話也就無所謂是鏈接查詢仍是子查詢,視本身的習慣而定。通常狀況下仍是用子查詢來的好,容易控制
sql
爲何子查詢比鏈接查詢(LEFT JOIN)效率低
MySQL從4.1版本開始支持子查詢,使用子查詢進行SELECT語句嵌套查詢,能夠一次完成不少邏輯上須要多個步驟才能完成的SQL操做。子查詢雖然很靈活,可是執行效率並不高。
那麼問題來了,什麼是子查詢?爲何它的效率不高?
子查詢:把內層查詢結果看成外層查詢的比較條件數據庫
示例:
select goods_id,goods_name from goods where goods_id = (select max(goods_id) from goods);
執行子查詢時,MYSQL須要建立臨時表,查詢完畢後再刪除這些臨時表,因此,子查詢的速度會受到必定的影響,這裏多了一個建立和銷燬臨時表的過程。服務器
優化方式:
可使用鏈接查詢(JOIN)代替子查詢,鏈接查詢不須要創建臨時表,所以其速度比子查詢快。ide
子查詢和關聯查詢的效率問題
MSDN對子查詢的定義是這樣的:函數
能夠將一個查詢的結果用做另外一個查詢的輸入。能夠將子查詢的結果用做使用 IN( ) 函數、EXISTS 運算符或 FROM 子句的語句。
一條好的值得稱讚的規則是儘可能用鏈接代替全部的子查詢。優化器有時能夠自動將子查詢「扁平化」,而且用常規或外鏈接代替。但那樣也不老是有效。明確的鏈接對選擇表的順序和找到最可能的計劃給出了更多的選項。當你優化一個特殊查詢時,瞭解一下是否去掉自查詢可產生很大的差別。這段話出自http://www.innovatedigital.com/htm_speek/SQLServerOpt.shtml它顯然告訴咱們在查詢的時候最好不要用子查詢,當時我並不太在乎,至到我有一次遇到了這樣的狀況。
如今的網站主要的壓力都來自於數據庫,頻繁的數據庫訪問常常會使服務器死機。個人原則就是儘可能減小數據庫的鏈接,能一次性取出的決很少鏈接數據庫一次,可是有時候並不徹底是這樣。鬱悶,無解。
下面一條SQL語句裏面有一個子查詢,info.RESOURCE_VOLUMECOUNT,它是指一個電影共有多少集.這個字段是int類型的.子查詢的目的就是計算出一個電影在資源表中總共有多少集(實際存在的), 二者作減法操做就能夠計算出這個電影共缺多少集(lastCount)咱們知道在這條語句執行的時候,外層記錄查詢一次在計算 lastCount字段的時候又要查詢表:電影表一次.若是最外層有10條記錄,那麼執行此次查詢一共要掃描電影表11次,鏈接數據庫1次.
優化
基於有的朋友看不明白我寫的SQL語句,多是由於我寫的有些字段和本案例沒有太大關係的緣由,如今特將它們作一個替換.網站
通過我的實踐,證實子查詢效率特別低,而通常的子查詢均可以由關連查詢來實現相同的功能,關聯查詢的效率要提升不少,因此建議在數據查詢時避免使用子查詢(尤爲是在記錄不少時),而最好用關聯查詢來實現。
如今舉例說明。
我作的是簡單的北京公交查詢系統,用的是MySQL數據庫,數據庫包含兩張表,line表和track表。line表有lid和lname兩個屬性,分別表示線路id和線路名稱。track表有lid,seq,sname,lo,la五個屬性,分別表示站點所在的線路id,站點在線路上的順序,站點名稱,站點的經度和緯度。如今要查詢某一給定線路名稱的線路上全部站點的經度和緯度。其中line中有1112條記錄,track中約有20萬條記錄。
子查詢sql語句:select lo,la from track where lid in (select lid from line where lname like '%lname%');
關聯查詢sql語句:select lo,la from track,line where line.lname like '%lname%' and line.lid=track.lid;
子查詢運行時間爲5分48秒;而關聯查詢耗時不足一秒。事實勝於雄辯,關聯查詢的優點不言而喻。
在關聯查詢時要注意:where子句中必定要包含表之間的鏈接條件,如 line.lid=track.lid,不然查詢結果會徹底超乎咱們的想象,形成沒必要要的麻煩。
參考連接: