操屁眼的视频在线免费看,日本在线综合一区二区,久久在线观看免费视频,欧美日韩精品久久综

新聞資訊

    聊聊慢SQL中關于IN語法的優(yōu)化分析過程。

    技術人人都可以磨煉,但處理問題的思路和角度各有不同,希望這篇文章可以拋磚引玉。

    以一個例子為切入點

    一、問題背景

    某業(yè)務模塊反饋SQL慢,優(yōu)化過程中的一些思考做個記錄。

    基礎環(huán)境:

    問題現(xiàn)象:慢SQL

    簡單說明:

    在很多應用場景中,SQL 的性能直接決定了系統(tǒng)的性能。此外,查詢速度慢并不只是因為 SQL 語句本身,還可能是因為內(nèi)存分配不佳、文件結構不合理、刷臟頁等其他原因。

    本文介紹一些通過調整 SQL 語句就能優(yōu)化SQL的通用小技巧,優(yōu)化 SQL 的方法不能解決所有的性能問題,但是卻能處理很多因 SQL 寫法不合理而產(chǎn)生的性能問題。

    二、分析說明

    三、疑問點排查及分析思路

    黃子韜明星庫_in子查詢數(shù)據(jù)庫怎么用_網(wǎng)易52g庫密碼庫查詢

    原SQL結構如下:

    *

    FROM tab_a

    WHERE ID IN ( c_id FROM tab_b);

    業(yè)務需求我看了一下in子查詢數(shù)據(jù)庫怎么用,還真不能怪開發(fā)小哥這么寫,我第一反應也是這么寫,用IN的好處就是SQL比較直觀,容易理解SQL邏輯。

    1、IN語法的SQL執(zhí)行計劃

    SQL如下:

    *

    FROM tab_a

    WHERE ID IN ( c_id FROM tab_b);

    黃子韜明星庫_網(wǎng)易52g庫密碼庫查詢_in子查詢數(shù)據(jù)庫怎么用

    執(zhí)行計劃如下:

    就這個SQL的執(zhí)行計劃本身來說還是不錯的(MySQL查詢轉換做的不錯),我想說的主要關注點在(tab_a)上。

    我們看到上面查詢計劃中,extra列可以看到 (tab_a) 。MySQL使用了連接來處理此查詢,對于tab_a表的行,只要能在tab_b表中找到1條滿足即可以不必再檢索tab_a表。從語義角度來看,和IN-to-EXIST策略轉換為Exist子句是相似的,區(qū)別就是以連接形式執(zhí)行查詢,而不是子查詢。

    策略背后的思想和in->轉換思想相同。有以下的優(yōu)點:

    策略意味著子查詢的表必須在父查詢中的表之后被引用,支持相關子查詢;不能應用于子查詢帶有group by或聚合函數(shù)的場景。

    PS:是否開啟是由系統(tǒng)變量中的=on|off設置的。

    2、語法的SQL執(zhí)行計劃

    SQL如下:

    a.*

    黃子韜明星庫_網(wǎng)易52g庫密碼庫查詢_in子查詢數(shù)據(jù)庫怎么用

    FROM tab_a a

    WHERE ( c_id FROM tab_b b where a.id=b.c_id);

    執(zhí)行計劃如下:

    通常來講, 比 IN 更快的原因有兩個:

    針對某一個查詢,有時候會有多種 SQL 實現(xiàn),例如 IN、、連接之間的互相轉換。從理論上來講,得到相同結果的不同 SQL 語句應該有相同的性能,但遺憾的是,查詢優(yōu)化器生成的執(zhí)行計劃很大程度上要受到外部結構的影響。

    因此,如果想優(yōu)化查詢性能,必須知道如何寫 SQL 語句才能使優(yōu)化器生成更高效的執(zhí)行計劃。

    3、使用代替IN是否更好?

    如果 IN 的參數(shù)是 1,2,3 這樣的數(shù)值列表,一般還不需要特別注意,但如果參數(shù)是子查詢,那么就需要注意了;在大多時候, [NOT] IN 和 [NOT] 返回的結果是相同的,但是兩者用于子查詢時, 的速度會更快一些。

    當 IN 的參數(shù)是子查詢時,數(shù)據(jù)庫有可能首先會執(zhí)行子查詢(上述分析案例不是),然后將結果存儲在一張臨時表里(內(nèi)聯(lián)視圖),然后掃描整個視圖,很多情況下這種做法非常耗費資源。而使用 的話,數(shù)據(jù)庫不會生成臨時表。

    減少臨時表也是在 SQL優(yōu)化中需要注意的點,子查詢的結果會被看成一張新表(臨時表),這張新表與原始表一樣,可以通過 SQL 進行操作。但是頻繁使用臨時表會帶來兩個問題:

    網(wǎng)易52g庫密碼庫查詢_in子查詢數(shù)據(jù)庫怎么用_黃子韜明星庫

    因此,盡量減少臨時表的使用也是提升性能的一個重要方法。

    4、其他代替IN的方案

    其實在平時工作當中,更多的是用連接代替 IN 來改善查詢性能,而非 ,不是說連接更好,而是 很難掌握(SQL邏輯不夠直白)。

    剛剛的SQL,如果用連接來實現(xiàn),如何寫?

    SQL如下:

    a.*

    FROM tab_b b left join tab_a a on b.c_id=a.id

    執(zhí)行計劃如下:

    這種寫法能充分利用索引;而且因為沒有了子查詢,所以數(shù)據(jù)庫也不會生成中間表;所以,查詢效率還是不錯的。至于 JOIN 與 相比哪個性能更好,不太好說;如果沒有索引,可能 會略勝一籌,有索引的話,兩者差不多。

    黃子韜明星庫_網(wǎng)易52g庫密碼庫查詢_in子查詢數(shù)據(jù)庫怎么用

    執(zhí)行計劃里需要注意的一個點是Using , 表示進行了排序或分組,顯然這個 SQL 沒有進行分組,而是進行了排序運算。

    為了排除重復數(shù)據(jù), 也會進行排序,而排序操作一般是要避免的,怎么避免?

    5、使用 代替

    還是剛剛的SQL,如果不用 過濾數(shù)據(jù),怎么寫?

    用 來進行優(yōu)化

    可以看到in子查詢數(shù)據(jù)庫怎么用,已經(jīng)規(guī)避了排序運算。

    總結

    文中雖然列舉了幾個要點,但其實優(yōu)化的核心思想只有一個,那就是找出性能瓶頸所在,然后解決它。不管是減少排序還是使用索引,亦或是避免臨時表的使用,其本質都是為了減少對硬盤的訪問。

    小技巧:

    覺得本文有用,請轉發(fā)、點贊或點擊“在看”聚焦技術與人文,分享干貨,共同成長更多內(nèi)容請關注“數(shù)據(jù)與人”

網(wǎng)站首頁   |    關于我們   |    公司新聞   |    產(chǎn)品方案   |    用戶案例   |    售后服務   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區(qū)    電話:010-     郵箱:@126.com

備案號:冀ICP備2024067069號-3 北京科技有限公司版權所有