1. 程式人生 > >MySQL IN子查詢

MySQL IN子查詢

近日通過《mysql技術內幕:SQL程式設計》學習mysql子查詢,書中介紹了IN子查詢存在的問題,並且提供了一些優化方法。我在此書的基礎上進行了深入研究,總結幾點。

MySql優化器對IN子查詢優化時存在一個問題,MySql優化器對於IN語句的優化是“LAZY”的。對於IN子句,如果不顯式的列表定義,如IN(‘a’,’b’,’c’),那麼IN子句都會被轉換為EXISTS的相關子查詢。如下面這條獨立子查詢:

select … from t1 where t1.a in (select b from t2)

優化器會將該語句重寫為如下的相關子查詢:

select … from t1 where exists (select 1 from t2 wheret1.a=t2.b)

如果子查詢和外部查詢分別返回M和N行,那麼該子查詢被掃描為O(N+M*N)而不是O(M+N)。

這一點在mysql官方文件中有參考,E.4.Restrictions on Subqueries。於是我通過mysql官方的示例資料庫employees進行了測試。

要求:查詢dept_no為d001的所有員工。

按照要求,我只需要使用子查詢在dept_emp表中選擇dept_no為d001的emp_no,然後使用IN關鍵字從employees表中選擇emp_no所在的記錄就可以,於是有:

select * from employees where emp_no in (select emp_nofrom dept_emp where dept_no='d001');

執行這條sql語句,總共查出20211條記錄,耗時2.078s。感覺是很慢的,但是也不知道到底多快算是合理。

使用EXPLAIN來檢視它的查詢計劃:

由上圖可知,子查詢的執行方式為相關子查詢,但是從sql語句來看,我寫的明明是獨立子查詢。看來正如mysql文件所說,優化器對sql進行了改寫。

按照mysql參考文件的說法,可以將該查詢改為聯結的方式。如下所示:

select * from employees emp,dept_emp de wheredept_no='d001' and emp.emp_no=de.emp_no;

執行結果相同,但是查詢時間變為了0.290s,速度提高了將近10倍,再EXPLAIN一下:

發現兩個查詢選擇型別都為SIMPLE。而且type列為eq_ref,比unique_subquery好很多。

相關推薦

眼睜睜地踩到 MySQL in 查詢的“坑”

前言 MySQL是專案中常用的資料庫,其中in查詢也是很常用。最近專案除錯過程中,遇到一個出乎意料的select查詢,竟然用了33秒! 一、表結構 1. userinfo 表 2. article 表 二、問題SQL例項 select*fromuserinfowhereidin(selectau

mysql in 查詢 效率慢 優化(轉)

現在的CMS系統、部落格系統、BBS等都喜歡使用標籤tag作交叉連結,因此我也嚐鮮用了下。但用了後發現我想查詢某個tag的文章列表時速度很慢,達到5秒之久!百思不解(後來終於解決),我的表結構是下面這樣的,文章只有690篇。 文章表article(id,title,content) 標籤表tag(tid,

MySQL IN查詢

近日通過《mysql技術內幕:SQL程式設計》學習mysql子查詢,書中介紹了IN子查詢存在的問題,並且提供了一些優化方法。我在此書的基礎上進行了深入研究,總結幾點。 MySql優化器對IN子查詢優化時存在一個問題,MySql優化器對於IN語句的優化是“LAZY”的。對於I

警惕 MySql 更新 sql 的 WHERE 從句中的 IN() 查詢時出現的效能陷阱

mer_stage 表有 216423 條記錄,DDL:CREATE TABLE `mer_stage` ( `STAGE_ID` int(11) NOT NULL AUTO_INCREMENT, `MER_ID` int(11) NOT NULL, `MER_C

mysql not in查詢返回結果為空

今天寫sql語句的時候,希望通過not in子查詢來限制查詢結果,實際SQL語句如下:  select  ID as id, TYPE_CODE as typeCode , TYPE_NAME as typeName , PARENT_ID as parentsId

MySQL Execution Plan--IN查詢包含超多值引發的查詢異常1

pos cos table HERE lock code 5.1 pic key ======================================================================= SQL語句: SELECT wave_n

MySQL--5查詢與連接小結

outer 比較運算符 limit 現在 order by select date ner 多表刪除 子查詢:出現在其他sql語句中的 SELECT,必須出現在小括號內,子查詢外層可以是常見的SELECT語句,INSERT語句 UPDATE語句 DELETE語句,在子查詢中

生產庫中遇到mysql查詢

.org href hid dba 情況 人員 使用 優化 弱點 使用過oracle或者其他關系數據庫的DBA或者開發人員都有這樣的經驗,在子查詢上都認為數據庫已經做過優化,能夠很好的選擇驅動表執行,然後在把該經驗移植到mysql數據庫上,但是不幸的是,mysql在子查詢的

mysql查詢作業

group by 準備 姓名 arch lte exists ins 語句 sql #數據準備drop table if exists class;create table class( class_no int(2) unsigned zerofill primar

如何提高MySql資料庫查詢的效率

做django的專案,用python語言寫查詢資料庫的語句,使用OuterRef, Subquery,Exists,F建立複雜的查詢語句: 資料庫模型: from django.db import models # 經緯度唯一表 class LngLat(models.Model):

讓天下沒有難用的資料庫 » 淺談mysql查詢

mysql的子查詢的優化一直不是很友好,一直有受業界批評比較多,也是我在sql優化中遇到過最多的問題之一,你可以點選這裡 ,這裡來獲得一些資訊,mysql在處理子查詢的時候,會將子查詢改寫,通常情況下,我們希望由內到外,也就是先完成子查詢的結果,然後在用子查詢來驅動外查詢的表,完成查詢,但是恰恰相反

讓天下沒有難用的資料庫 » 生產庫中遇到mysql查詢

使用過oracle或者其他關係資料庫的DBA或者開發人員都有這樣的經驗,在子查詢上都認為資料庫已經做過優化,能夠很好的選擇驅動表執行,然後在把該經驗移植到mysql資料庫上,但是不幸的是,mysql在子查詢的處理上有可能會讓你大失所望,在我們的生產系統上就由於碰到了這個問題: select  i_i

mysql---where查詢、form查詢、exists查詢

create table article(article_id int(3),article_title varchar(50),article_content text,article_comments int(3),articlecategory_id int(3) ); insert into arti

Mysql from 查詢問題? 隨筆

表結構 goods_id,goods_namefrom(*FROM`goods`WHERE1ORDERBYcat_idASC,goods_idDESC)astmpgroupbycat_id 上面的

MySQL#利用查詢更新

MySql利用子查詢更新 示例1 update t_pandora_bill_summary as ua inner join (select g1.sho

Mysql update 查詢鎖表問題。

今天碰到詭異的表死鎖問題。 首先Tomcat報錯: Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackExcept

mysql update 查詢

select max(id) as id from djgl_dzqt_replace_audit where audit_genre = 3  and audit_result = 0  and state = 0 and business_id = 2; SELECT

mysql in 條件中不支援limit

mysql in 子條件中不支援limit ,再巢狀一層即可 where corp_id=#{corpId} and person_id=#{personId} and end_atten_date>#{endAttenDate} and uuid not in(

MySQL UPDATE查詢

- update services a,(select concat(services_time,'分鐘') as services_time,services_id from services) b set a.services_time =

SQL IN 查詢返回多個值

下午遇到一個問題,IN子查詢返回多個值。 網上查了很多文件,資料,都沒收穫。 問了技術群的同僚,竟然還被嘲笑了。IN 怎麼可能匹配多個欄位呢! 個人印象中曾經在哪裡見到過,所以就覺得不服氣。自己慢慢地去試,試出來了。 我們常用的IN 操作是這樣的: s