亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

MySQL 查詢速度慢的原因

 更新時(shí)間:2021年05月25日 09:54:01   作者:xcbeyond  
高性能MySQL需要合理的設(shè)計(jì)查詢。如果查詢寫的很糟糕,即使表結(jié)構(gòu)再合理、索引再合適,也是無法實(shí)現(xiàn)高性能的。

談到MySQL性能優(yōu)化,查詢優(yōu)化作為優(yōu)化的源頭,它也是最能體現(xiàn)一個(gè)系統(tǒng)是否更快。本章以及接下來的幾章將會(huì)著重講解關(guān)于查詢性能優(yōu)化的內(nèi)容,從中會(huì)介紹一些查詢優(yōu)化的技巧,幫助大家更深刻地理解MySQL如何真正地執(zhí)行查詢、究竟慢在哪里、如何讓其快起來,并明白高效和低效的原因何在,這樣更有助于你更好的來優(yōu)化查詢SQL語句。

本章從“為什么查詢速度這么慢”開始談起,讓你能夠清楚的知道查詢可能會(huì)慢在哪些環(huán)節(jié),這樣將有助于你更好的優(yōu)化查詢,做到心中有數(shù),高人一籌。

一、慢在哪?

**真正衡量查詢速度的是響應(yīng)時(shí)間。**如果把查詢看作是一個(gè)任務(wù),那么它是由一系列子任務(wù)組成的,每個(gè)任務(wù)都會(huì)消耗一定的時(shí)間。如果要優(yōu)化查詢,實(shí)際上要優(yōu)化其子任務(wù),那么消除其中一些子任務(wù),那么減少子任務(wù)的執(zhí)行次數(shù),要么讓子任務(wù)運(yùn)行的更快。

MySQL在執(zhí)行查詢的時(shí)候,有哪些子任務(wù),哪些子任務(wù)花費(fèi)的時(shí)間最多?這就需要借助一些工具,或者一些方法(如:執(zhí)行計(jì)劃)對查詢進(jìn)行剖析,來定位發(fā)現(xiàn)究竟慢在哪。

通常來說,查詢的生命周期大致大致可以按照順序來看:**從客戶端到服務(wù)器,然后在服務(wù)器上進(jìn)行解析,生成執(zhí)行計(jì)劃,執(zhí)行,并返回結(jié)果給客戶端。**其中,“執(zhí)行”可以認(rèn)為是整個(gè)生命周期中最重要的階段,這其中包括了大量為了檢索數(shù)據(jù)到存儲(chǔ)引擎的調(diào)用以及調(diào)用后的數(shù)據(jù)處理,包括排序、分組等。

在完成這些任務(wù)的時(shí)候,查詢需要在不同階段的不同地方花費(fèi)時(shí)間,包括網(wǎng)絡(luò)、CPU計(jì)算,生成統(tǒng)計(jì)信息和執(zhí)行計(jì)劃、鎖等待等操作,尤其是向底層存儲(chǔ)引擎檢索數(shù)據(jù)的調(diào)用操作,這些調(diào)用需要在內(nèi)存操作、CPU操作,還可能會(huì)產(chǎn)生大量的上下文切換以及系統(tǒng)調(diào)用。

在上述這些操作中,都會(huì)消耗大量的時(shí)間,其中會(huì)存在一些不必要的額外操作,其中有些操作可能被額外地重復(fù)執(zhí)行了很多次、某些操作執(zhí)行的很慢等等。這也就是查詢真正可能慢的地方,優(yōu)化查詢的目的就是減少和消除這些操作所花費(fèi)的時(shí)間。

通過上面的分析,我們對查詢的過程有了整體的了解,能夠清楚的知道查詢可能在哪些地方會(huì)存在問題,最終導(dǎo)致整個(gè)查詢很慢,為實(shí)際查詢優(yōu)化提供方向。

換言之,查詢優(yōu)化可以從以下兩個(gè)角度來出發(fā):

  • 減少子查詢次數(shù)
  • 減少額外、重復(fù)的操作

查詢性能低下常見的原因是訪問的數(shù)據(jù)太多。在數(shù)據(jù)量小的時(shí)候,查詢速度還不錯(cuò),一旦數(shù)據(jù)量上來,查詢速度將會(huì)發(fā)生巨變,讓人抓狂、體驗(yàn)極差。針對查詢優(yōu)化方面,可以從以下方面進(jìn)行排查:

  • 是否查詢了不需要的數(shù)據(jù)
  • 是否掃描了額外的記錄

二、是否查詢了不需要的數(shù)據(jù)

在實(shí)際查詢中很多時(shí)候,會(huì)查詢了實(shí)際需要的數(shù)據(jù),然后這些多余的數(shù)據(jù)會(huì)被應(yīng)用程序丟棄。這對MySQL來說是額外的開銷,同時(shí)也會(huì)消耗應(yīng)用服務(wù)器的CPU和內(nèi)存資源。

一些典型案例如下:

1. 查詢不需要的記錄

這是一個(gè)常見的錯(cuò)誤,常常會(huì)誤以為MySQL只會(huì)返回需要的數(shù)據(jù),實(shí)際上MySQL卻是先返回全部結(jié)果集再進(jìn)行計(jì)算。

開發(fā)者習(xí)慣性的先使用SELECT語句查詢大量的結(jié)果,然后由應(yīng)用查詢或者前端展示層再獲取前面的N行數(shù)據(jù),例如,在新聞網(wǎng)站中查詢100條記錄,但是只是在頁面上顯示前10條。

最有效的解決方法是需要多少記錄就查詢多少記錄,通常會(huì)在查詢后面加上LIMIT,即:分頁查詢。

2. 多表關(guān)聯(lián)時(shí)返回全部列

如果你想查詢所有在電影Academy Dinosaur中出現(xiàn)的演員,千萬不要按下面的方式來進(jìn)行查詢:

select * fromt actor a
inner join film_actor fa.actorId = a.actorId
inner join film f f.filmId = fa.filmId
where fa.title = 'Academy Dinosaur';

這樣將會(huì)返回三張表的全部數(shù)據(jù)列,而實(shí)際需求是要查詢演員信息,正確的寫法應(yīng)該是:

select a.* fromt actor a
inner join film_actor fa.actorId = a.actorId
inner join film f f.filmId = fa.filmId
where fa.title = 'Academy Dinosaur';

3. 總是查詢出全部列

每次看到select *的時(shí)候一定要用異樣的目光來審視它,是不是真的需要返回全部數(shù)據(jù)列?

在大部分情況下,是不需要的。select *會(huì)導(dǎo)致進(jìn)行全表掃描,會(huì)讓優(yōu)化器無法完成索引掃描這類優(yōu)化,過多的列還會(huì)為服務(wù)器帶來額外的I/O、內(nèi)存和CPU的消耗。即使真的需要查詢出全部列,應(yīng)該逐個(gè)羅列出全部列而不是*。

4. 重復(fù)查詢相同的數(shù)據(jù)

如果你不太留意,很容易出現(xiàn)這樣的錯(cuò)誤:不斷地重復(fù)執(zhí)行相同的查詢,然后每次都返回完全相同的數(shù)據(jù)。

例如,在用戶評(píng)論的地方需要查詢用戶頭像的URL,那么用戶多次評(píng)論的時(shí)候,可能就會(huì)反復(fù)來查詢這個(gè)數(shù)據(jù)。比較好處理方法是,在初次查詢的時(shí)候?qū)⑦@個(gè)數(shù)據(jù)緩存起來,后續(xù)使用時(shí)直接從緩存中取出。

三、是否掃描了額外的記錄

確定查詢只查詢了需要的數(shù)據(jù)以后,接下來應(yīng)該看看查詢過程中是否掃描了過多的數(shù)據(jù)。對于MySQL,最簡單衡量查詢開銷的三個(gè)指標(biāo)如下:

  • 響應(yīng)時(shí)間
  • 掃描的行數(shù)
  • 返回的行數(shù)

沒有哪個(gè)指標(biāo)能夠完全來衡量查詢的開銷,但它們能夠大致反映MySQL內(nèi)部執(zhí)行查詢時(shí)需要訪問多少數(shù)據(jù),并可以大概推算出查詢運(yùn)行的實(shí)際。這三個(gè)指標(biāo)都會(huì)記錄到MySQL的慢日志中,所以檢查慢日志記錄是找出掃描行數(shù)過多查詢的辦法。

慢查詢:用于記錄在MySQL中響應(yīng)時(shí)間超過閾值(long_query_time,默認(rèn)10s)的語句,并會(huì)將慢查詢記錄到慢日志中??赏ㄟ^變量slow_query_long來開啟慢查詢,默認(rèn)是關(guān)閉狀態(tài),可以將慢日志記錄到表slow_log或文件中,以供檢查分析。

1. 響應(yīng)時(shí)間

響應(yīng)時(shí)間是兩個(gè)部分之和:服務(wù)時(shí)間和排隊(duì)時(shí)間。服務(wù)時(shí)間是指數(shù)據(jù)庫處理這個(gè)查詢真正花費(fèi)了多長時(shí)間。排隊(duì)時(shí)間是指服務(wù)器因?yàn)榈却承┵Y源而沒有真正執(zhí)行查詢的時(shí)間,可能是等待I/O操作,也可能是等待行鎖等等。

在不同類型的應(yīng)用壓力下,響應(yīng)時(shí)間并沒有什么一致的規(guī)律或者公式。諸如存儲(chǔ)引擎的鎖(表鎖,行鎖),高并發(fā)資源競爭,硬件響應(yīng)等諸多因素都會(huì)影響響應(yīng)時(shí)間,所以,響應(yīng)時(shí)間既可能是一個(gè)問題的結(jié)果也可能是一個(gè)問題的原因,不同案例情況不同。

當(dāng)你看到一個(gè)查詢的響應(yīng)時(shí)間的時(shí)候,首先需要問問自己,這個(gè)響應(yīng)時(shí)間是否是一個(gè)合理的值。

2. 掃描的行數(shù)和返回的行數(shù)

在分析查詢時(shí),查看該查詢掃描的行數(shù)是非常有幫助的,在此之上也能夠分析是否掃描了額外的記錄。

對于找出那些糟糕查詢,這個(gè)指標(biāo)可能還不夠完美,因?yàn)椴⒉皇撬行械脑L問代價(jià)都是相同的。較短的行的訪問速度相當(dāng)快,內(nèi)存中的行也比磁盤中的行的訪問速度要快的多。

**理想的情況下,掃描的行數(shù)和返回的行數(shù)應(yīng)該是相同的。**但實(shí)際上這種美事并不多,例如在做一個(gè)關(guān)聯(lián)查詢的時(shí)候,掃描的行數(shù)和對返回的行數(shù)的比率通常都很小,一般在1:1和10:1之間,不過有時(shí)候這個(gè)值也可能非常大。

3. 掃描的行數(shù)和訪問類型

在評(píng)估查詢開銷的時(shí)候,需要考慮一下從表中找到某一行數(shù)據(jù)的成本。MySQL有好幾種訪問方式可以查找并返回一行結(jié)果。這些訪問方式可能需要訪問很多行才能返回一條結(jié)果,也有些訪問方式可能無需掃描就能返回結(jié)果。

在執(zhí)行計(jì)劃EXPLAIN語句中的type列反映了訪問類型。訪問類型有很多種,從全表掃描到索引掃描,范圍掃描,唯一索引,常數(shù)索引等。這里列的這些,速度是從慢到快,掃描的行數(shù)也是從多到少。

如果查詢沒有辦法找到合適的訪問類型,那么解決的最好辦法通常就是增加一個(gè)合適的索引,這也是我們之前討論索引的問題?,F(xiàn)在應(yīng)該明白為什么索引對于查詢優(yōu)化如此重要了。索引讓MySQL以最高效,掃描行數(shù)最少的方式找到需要的記錄。

如果發(fā)現(xiàn)查詢掃描了大量的數(shù)據(jù)但只返回少數(shù)的行,通??梢試L試下面的技巧去優(yōu)化它:

  • 使用索引覆蓋掃描,把所有需要用的列都放到索引中,這樣存儲(chǔ)引擎無需回表獲取對應(yīng)的行就可以返回結(jié)果了。
  • 優(yōu)化表結(jié)構(gòu)。例如使用單獨(dú)的匯總表來完成查詢。
  • 重寫復(fù)雜查詢,讓MySQL優(yōu)化器能夠以更優(yōu)化的方式執(zhí)行這個(gè)查詢。

以上就是MySQL 查詢速度慢的原因的詳細(xì)內(nèi)容,更多關(guān)于MySQL 查詢速度慢的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • MySQL內(nèi)部函數(shù)的超詳細(xì)介紹

    MySQL內(nèi)部函數(shù)的超詳細(xì)介紹

    眾所周知MySQL有很多內(nèi)置的函數(shù),下面這篇文章主要給大家介紹了關(guān)于MySQL內(nèi)部函數(shù)的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2022-08-08
  • MySQL查看用戶權(quán)限及權(quán)限管理的方法詳解

    MySQL查看用戶權(quán)限及權(quán)限管理的方法詳解

    在MySQL中,查看用戶權(quán)限可以通過多種方式實(shí)現(xiàn),主要取決于我們想要查看的權(quán)限類型和詳細(xì)程度,本文給大家介紹了MySQL查看用戶權(quán)限及權(quán)限管理的方法,并通過代碼示例介紹的非常詳細(xì),需要的朋友可以參考下
    2024-03-03
  • 淺談Mysql主鍵索引與非主鍵索引區(qū)別

    淺談Mysql主鍵索引與非主鍵索引區(qū)別

    本文主要介紹了ysql主鍵索引與非主鍵索引區(qū)別,文中介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-09-09
  • mysql查看連接數(shù)和設(shè)置會(huì)話超時(shí)問題

    mysql查看連接數(shù)和設(shè)置會(huì)話超時(shí)問題

    這篇文章主要介紹了mysql查看連接數(shù)和設(shè)置會(huì)話超時(shí)問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • 深入理解MySQL事務(wù)的4種隔離級(jí)別

    深入理解MySQL事務(wù)的4種隔離級(jí)別

    本文主要介紹了MySQL事務(wù)的4種隔離級(jí)別,事務(wù)的4種隔離級(jí)別分別是讀未提交,讀已提交,可重復(fù)讀和串行化,具有一定的參考價(jià)值,感興趣的可以了解一下
    2022-04-04
  • MySQL 8.0.18 穩(wěn)定版發(fā)布! Hash Join如期而至

    MySQL 8.0.18 穩(wěn)定版發(fā)布! Hash Join如期而至

    MySQL 8.0.18 穩(wěn)定版發(fā)布! Hash Join 如期而至,這篇文章帶大家快速瀏覽一下MySQL 8.0.18 穩(wěn)定版的各個(gè)亮點(diǎn),感興趣的小伙伴們可以學(xué)習(xí)參考一下
    2019-10-10
  • php+mysql prepare 與普通查詢的性能對比實(shí)例講解

    php+mysql prepare 與普通查詢的性能對比實(shí)例講解

    prepare可以解決大訪問量的網(wǎng)站給數(shù)據(jù)庫服務(wù)器所帶來的負(fù)載和開銷,本文章通過實(shí)例向大家介紹預(yù)查詢prepare與普通查詢的性能對比,需要的朋友可以參考一下
    2016-11-11
  • mysql having用法解析

    mysql having用法解析

    having字句可以讓我們篩選成組后的各種數(shù)據(jù),where字句在聚合前先篩選記錄,也就是說作用在group by和having字句前,下面通過實(shí)例給大家介紹mysql having用法,一起看看吧
    2017-10-10
  • 如何解決MySQL5升級(jí)為MySQL8遇到的問題my.ini

    如何解決MySQL5升級(jí)為MySQL8遇到的問題my.ini

    這篇文章主要介紹了如何解決MySQL5升級(jí)為MySQL8遇到的問題my.ini,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • innodb_flush_method取值方法(實(shí)例講解)

    innodb_flush_method取值方法(實(shí)例講解)

    下面小編就為大家?guī)硪黄猧nnodb_flush_method取值方法(實(shí)例講解)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-03-03

最新評(píng)論