亚洲欧美日韩综合系列在线_91精品人妻一区二区_欧美大肥婆一级特大AA片_九色91视频免费观看_亚洲综合国产精品_av中文字幕在线不卡_久久精品色综合网_看黄色视频的软件_无卡无码高清中文字幕码2024_亚洲欧美日韩天堂网

為什么不要使用IN而要使用EXISTS

來(lái)源:20Hui 發(fā)布時(shí)間:2018-11-01 10:14:14 閱讀量:1106

今天發(fā)現(xiàn)SQL語(yǔ)句執(zhí)行速度過(guò)慢,然后我就認(rèn)真看了看,用EXPLAIN看了一下


SQL


SELECT

    count(*)

FROM

    student_info AS s

LEFT JOIN class ON s.class_id = class.id

LEFT JOIN major AS m ON class.major_id = m.id

LEFT JOIN department AS d ON m.department_id = d.id

LEFT JOIN college AS c ON d.college_id = c.id

WHERE

    s.student_number NOT IN (

        SELECT

            b.student_id

        FROM

            bed AS b

        WHERE

            b.student_id IS NOT NULL

        ORDER BY

            b.student_id

    )

EXPLAIN




我發(fā)現(xiàn)這樣SQL的執(zhí)行速度太慢了,我就想著有什么辦法可以?xún)?yōu)化。


網(wǎng)上那些count(1)、count(屬性),我都試過(guò)了,感覺(jué)變化不大


這個(gè)時(shí)候,我的師兄就給了一個(gè)建議,你不要使用IN,你使用EXIST,我之前就已經(jīng)知道IN的性能要差于EXIST,但是心理一直沒(méi)有一個(gè)概念,我就聽(tīng)從師兄的建議,將NOT IN轉(zhuǎn)換為 NOT EXISTS,然后我又EXPLAIN一下。


SQL


SELECT

    count(*)

FROM

    student_info AS s

LEFT JOIN class ON s.class_id = class.id

LEFT JOIN major AS m ON class.major_id = m.id

LEFT JOIN department AS d ON m.department_id = d.id

LEFT JOIN college AS c ON d.college_id = c.id

WHERE

    NOT EXISTS (

        SELECT

    b.student_id

FROM

    bed AS b

WHERE

    b.student_id IS NOT NULL

AND b.student_id = s.student_number

ORDER BY

    b.student_id

    )

EXPLAIN




通過(guò)對(duì)比我們就發(fā)現(xiàn),bed的索引,從rang變成ref,我又去百度了一下,他們兩個(gè)之間的差距。


system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL


震驚吧,他們之間相差這么多個(gè)量級(jí)。


然后他們之間的差距我們可以通過(guò)定義看出來(lái)


rang:range指的是有范圍的索引掃描,相對(duì)于index的全索引掃描,它有范圍限制,因此要優(yōu)于index。關(guān)于range比較容易理解,需要記住的是出現(xiàn)了range,則一定是基于索引的。同時(shí)除了顯而易見(jiàn)的between,and以及'>','<'外,in和or也是索引范圍掃描。


ref:出現(xiàn)該連接類(lèi)型的條件是: 查找條件列使用了索引而且不為主鍵和unique。其實(shí),意思就是雖然使用了索引,但該索引列的值并不唯一,有重復(fù)。這樣即使使用索引快速查找到了第一條數(shù)據(jù),仍然不能停止,要進(jìn)行目標(biāo)值附近的小范圍掃描。但它的好處是它并不需要掃全表,因?yàn)樗饕怯行虻?,即便有重?fù)值,也是在一個(gè)非常小的范圍內(nèi)掃描。


你們知道了吧,IN是走rang,就是最差的索引=沒(méi)有索引,而EXISTS走的ref,已經(jīng)算是比較好的檢索方式了。


記住了,以后不要再使用IN,要使用EXISTS了

--------------------- 

作者:20Hui 

來(lái)源:CSDN 

原文:https://blog.csdn.net/weixin_37645838/article/details/83585505 

版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請(qǐng)附上博文鏈接!


標(biāo)簽: 數(shù)據(jù)庫(kù)
分享:
評(píng)論:
你還沒(méi)有登錄,請(qǐng)先