最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MySQL中(JOIN/ORDER BY)語(yǔ)句的查詢過(guò)程及優(yōu)化方法

 更新時(shí)間:2019年05月21日 14:59:48   作者:陳小峰_iefreer  
sql語(yǔ)句性能達(dá)不到你的要求,執(zhí)行效率讓你忍無(wú)可忍,一般會(huì)造成很多影響。那么我們?nèi)绾谓鉀Q這些問(wèn)題呢,下面由小編來(lái)和大家簡(jiǎn)單講下

MySQL查詢語(yǔ)句過(guò)程和EXPLAIN語(yǔ)句基本概念及其優(yōu)化中介紹了EXPLAIN語(yǔ)句,并舉了一個(gè)慢查詢例子:

可以看到上述的查詢需要檢查1萬(wàn)多記錄,并且使用了臨時(shí)表和filesort排序,這樣的查詢?cè)谟脩魯?shù)快速增長(zhǎng)后將成為噩夢(mèng)。

在優(yōu)化這個(gè)語(yǔ)句之前,我們先了解下SQL查詢的基本執(zhí)行過(guò)程:

1.應(yīng)用通過(guò)MySQL API把查詢命令發(fā)送給MySQL服務(wù)器,然后被解析

2.檢查權(quán)限、MySQL optimizer進(jìn)行優(yōu)化,經(jīng)過(guò)解析和優(yōu)化后的查詢命令被編譯為CPU可運(yùn)行的二進(jìn)制形式的查詢計(jì)劃(query plan),并可以被緩存

3.如果存在索引,那么先掃描索引,如果數(shù)據(jù)被索引覆蓋,那么不需要額外的查找,如果不是,根據(jù)索引查找和讀取對(duì)應(yīng)的記錄

4.如果有關(guān)聯(lián)查詢,查詢次序是掃描第一張表找到滿足條件的記錄,按照第一張表和第二張表的關(guān)聯(lián)鍵值,掃描第二張表查找滿足條件的記錄,按此順序循環(huán)

5.輸出查詢結(jié)果,并記錄binary logs

顯然合適的索引將大大簡(jiǎn)化和加速查找。再看一下上面那條查詢語(yǔ)句,除了條件查詢外,還有關(guān)聯(lián)查詢以及ORDER BY即排序操作,

那么讓我們進(jìn)一步了解下關(guān)聯(lián)查詢(JOIN)和ORDER BY是怎么工作的,MySQL有三種方式來(lái)處理關(guān)聯(lián)查詢和數(shù)據(jù)排序:

第一種方法是基于索引,第二種是對(duì)第一個(gè)非常量表進(jìn)行filesort(quicksort),還有一種是把聯(lián)合查詢的結(jié)果放入臨時(shí)表,然后進(jìn)行filesort。

注1:關(guān)于什么是非常量表,請(qǐng)參考閱讀MySQL開(kāi)發(fā)手冊(cè):Consts and Constant Tables,
注2:什么是filesort呢,這不是字面意思的文件排序,filesort有兩種模式:
1、模式1:排序后的元素涵蓋了要輸出的數(shù)據(jù)。排序結(jié)果是一串有序序列元素組,不再需要額外的記錄讀??;
2、模式2:排序結(jié)果是<sort_key,row_id>鍵值對(duì)序列,通過(guò)這些row_ids再去讀取記錄(隨機(jī)讀取,效率低下);
注3:關(guān)于什么是臨時(shí)表,請(qǐng)參考閱讀MySQL開(kāi)發(fā)手冊(cè):How MySQL Uses Internal Temporary Tables

第一種方法用于第一個(gè)非常量表中存在ORDER BY所依賴的列的索引,那就可直接使用已經(jīng)有序的索引來(lái)查找關(guān)聯(lián)表的數(shù)據(jù),這種方式是性能最優(yōu)的,因?yàn)椴恍枰~外的排序動(dòng)作:

第二種方式用于ORDER BY所依賴的列全部屬于第一張查詢表且沒(méi)有索引,那么我們可以先對(duì)第一張表的記錄進(jìn)行filesort(模式可能是模式1也可能是模式2),得到有序行索引,然后再做關(guān)聯(lián)查詢,filesort的結(jié)果可能是在內(nèi)存中,也可能在硬盤上,這取決于系統(tǒng)變量sort_buffer_size(一般為2M左右):

第三種方法用于當(dāng)ORDER BY的元素不屬于第一張表時(shí),需要把關(guān)聯(lián)查詢的結(jié)果放入臨時(shí)表,最后對(duì)臨時(shí)表進(jìn)行filesort:

第三種方法中的臨時(shí)表,可能是在內(nèi)存中(in-memory table),也可能是在硬盤上,一般是下面兩種情況會(huì)使用硬盤(on-disk table):

(1)使用了BLOB,TEXT類型的數(shù)據(jù)

(2)內(nèi)存表占用超過(guò)了系統(tǒng)變量tmp_table_size/max_heap_table_size的限定(一般為16M左右),只能放在硬盤上

從上面的查詢執(zhí)行過(guò)程和方式,我們應(yīng)該可以清楚的知道為什么Using filesort,Using temporary會(huì)嚴(yán)重的影響查詢性能,因?yàn)槿绻麛?shù)據(jù)類型或者字段設(shè)計(jì)有問(wèn)題,

在需要查詢的表以及結(jié)果中存在大數(shù)據(jù)的字段,而沒(méi)有合適的索引可用時(shí),都可能會(huì)導(dǎo)致產(chǎn)生大量的IO操作,這就是查詢性能緩慢的根源所在。

回到文章開(kāi)頭所舉的查詢實(shí)例,它顯然是使用了效率最低的第三種方法,我們需要做和嘗試的優(yōu)化手段有:

1、為users.fl_no添加索引,為select和where所使用的字段建立索引

2、把users.fl_no轉(zhuǎn)移到或者作為冗余字段添加到表user_profile中

3、去除TEXT類型的字段,TEXT可以替換為VARCHAR(65535)或?qū)τ谥形亩訴ARCHAR(20000)

4、如果實(shí)在無(wú)法消除Using filesort,那么提高sort_buffer_size,以減少IO操作負(fù)擔(dān)

5、盡量使用第一張表所覆蓋的索引進(jìn)行排序,實(shí)在不行,可以把排序邏輯從MySQL中移到PHP/Java程序中執(zhí)行

實(shí)施1、2、3的優(yōu)化方法后,EXPLAIN結(jié)果如下:

備注:編寫簡(jiǎn)單的PHP應(yīng)用,用siege測(cè)試,查詢效率提高>3倍。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • mysql對(duì)于模糊查詢like的一些匯總

    mysql對(duì)于模糊查詢like的一些匯總

    這篇文章主要給大家介紹了關(guān)于mysql對(duì)于模糊查詢like的一些匯總,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • MySQL本地版本升級(jí)超詳細(xì)教程(從5.5.20升到8.0.21)

    MySQL本地版本升級(jí)超詳細(xì)教程(從5.5.20升到8.0.21)

    MySQL是一款廣泛使用的關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng),但是舊版本的客戶端可能會(huì)受到一些限制,下面這篇文章主要給大家介紹了關(guān)于MySQL本地版本升級(jí)超詳細(xì)教程,本文是從5.5.20升到8.0.21的相關(guān)資料,需要的朋友可以參考下
    2023-04-04
  • phpstudy無(wú)法啟動(dòng)MySQL數(shù)據(jù)庫(kù)解決方法

    phpstudy無(wú)法啟動(dòng)MySQL數(shù)據(jù)庫(kù)解決方法

    這篇文章主要給大家介紹了關(guān)于phpstudy無(wú)法啟動(dòng)MySQL數(shù)據(jù)庫(kù)的解決方法,文中通過(guò)圖文將解決的辦法介紹的非常詳細(xì),對(duì)同樣遇到這個(gè)問(wèn)題的同學(xué)具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2024-05-05
  • 如何設(shè)置才能遠(yuǎn)程登錄Mysql數(shù)據(jù)庫(kù)

    如何設(shè)置才能遠(yuǎn)程登錄Mysql數(shù)據(jù)庫(kù)

    本地機(jī)器安裝的數(shù)據(jù)庫(kù),本地程序可以訪問(wèn),但是同事的機(jī)器卻無(wú)法連接訪問(wèn),發(fā)現(xiàn)是mysql數(shù)據(jù)庫(kù)沒(méi)有開(kāi)啟遠(yuǎn)程訪問(wèn)。那么我們需要如何設(shè)置呢,這就是本文探討的內(nèi)容了
    2014-08-08
  • 基于mysql+mycat搭建穩(wěn)定高可用集群負(fù)載均衡主備復(fù)制讀寫分離操作

    基于mysql+mycat搭建穩(wěn)定高可用集群負(fù)載均衡主備復(fù)制讀寫分離操作

    這篇文章主要介紹了基于mysql+mycat搭建穩(wěn)定高可用集群負(fù)載均衡主備復(fù)制讀寫分離操作,需要的朋友可以參考下
    2018-09-09
  • mysql關(guān)聯(lián)兩張表時(shí)的編碼問(wèn)題及解決辦法

    mysql關(guān)聯(lián)兩張表時(shí)的編碼問(wèn)題及解決辦法

    在本篇文章里小編給大家整理的是關(guān)于mysql關(guān)聯(lián)兩張表時(shí)的編碼問(wèn)題及解決辦法,有需要的朋友們可以參考下。
    2019-09-09
  • mysql函數(shù)之截取字符串的實(shí)現(xiàn)

    mysql函數(shù)之截取字符串的實(shí)現(xiàn)

    本文主要介紹了mysql函數(shù)之截取字符串的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • 記一次MySQL Slave庫(kù)恢復(fù)實(shí)戰(zhàn)記錄

    記一次MySQL Slave庫(kù)恢復(fù)實(shí)戰(zhàn)記錄

    這篇文章主要介紹了記一次MySQL Slave庫(kù)恢復(fù)實(shí)戰(zhàn)記錄,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • Canal入門使用小結(jié)

    Canal入門使用小結(jié)

    Canal是一款MySQL數(shù)據(jù)庫(kù)增量日志解析工具,用于實(shí)現(xiàn)數(shù)據(jù)庫(kù)之間的數(shù)據(jù)同步,本文主要介紹了Canal入門使用小結(jié),感興趣的可以了解一下
    2025-02-02
  • kali虛擬機(jī)mysql修改綁定ip的問(wèn)題

    kali虛擬機(jī)mysql修改綁定ip的問(wèn)題

    這篇文章主要介紹了kali虛擬機(jī)mysql修改綁定ip,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-06-06

最新評(píng)論

黑水县| 江油市| 井研县| 武功县| 伽师县| 吉木萨尔县| 浪卡子县| 静海县| 蛟河市| 田阳县| 太康县| 天峨县| 九台市| 会理县| 大邑县| 稻城县| 涿州市| 金门县| 桂阳县| 阳谷县| 临夏县| 洮南市| 宁夏| 长海县| 边坝县| 海林市| 潼关县| 凤台县| 钦州市| 增城市| 璧山县| 榕江县| 玛纳斯县| 钟祥市| 安泽县| 丰原市| 江陵县| 定远县| 清苑县| 玛纳斯县| 罗山县|