溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何利用MySQL進行慢查詢以及重構(gòu)查詢

發(fā)布時間:2021-06-16 13:52:25 來源:億速云 閱讀:111 作者:chen 欄目:開發(fā)技術(shù)

這篇文章主要介紹“如何利用MySQL進行慢查詢以及重構(gòu)查詢”,在日常操作中,相信很多人在如何利用MySQL進行慢查詢以及重構(gòu)查詢問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”如何利用MySQL進行慢查詢以及重構(gòu)查詢”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!

前言

什么是慢查詢,如何優(yōu)化慢查詢,下面介紹這兩個知識點的相關(guān)知識。

慢查詢基礎(chǔ):優(yōu)化數(shù)據(jù)訪問

是否向數(shù)據(jù)庫請求了不需要的數(shù)據(jù)

查詢不需要的記錄:解決方案:查詢后面加上Limit

多表關(guān)聯(lián)時返回全部列:解決方案:只取需要的列

總是取出全部列:select * 解決方案:最好還是獲取部分列,除非應(yīng)用程序處緩存列的數(shù)據(jù)了

重復(fù)查詢相同的數(shù)據(jù):解決方案:需要時從緩存中取出

MySQL是否在掃描額外的記錄

可以從響應(yīng)時間,掃描的行數(shù),返回的行數(shù)來進行查詢開銷的衡量。

要想減少掃描行數(shù)可以使用索引對需要的記錄進行覆蓋,但是增加索引不意味著就能讓掃描的行數(shù)等于返回的行數(shù),比如sum,count之類的聚合函數(shù)

重構(gòu)查詢的方法

一個復(fù)雜查詢還是多個簡單查詢

在過去,總是強調(diào)需要數(shù)據(jù)庫層完成盡可能多的工作,因為過去網(wǎng)絡(luò)通信查詢解析和優(yōu)化是一件代價很高的事情。

但是這樣的想法對于MySQL并不適用,MySQL從設(shè)計上讓連接和斷開連接都很輕量級,在返回一個小的查詢結(jié)果方面很高效?,F(xiàn)代的網(wǎng)絡(luò)速度比以前要快很多,無論是帶寬還是延遲。在某些版本的MySQL上,即使在一個通用服務(wù)器上,也能夠運行每秒超過10萬的查詢,即使是一個千兆網(wǎng)卡也能輕松滿足每秒超過2000次的查詢。所以運行多個小查詢現(xiàn)在已經(jīng)不是大問題了。

當(dāng)然,相比較于內(nèi)部掃描,響應(yīng)數(shù)據(jù)給客戶端更加耗時,所以在同條件下,使用盡可能少的查詢更好。

切分查詢

當(dāng)使用sql進行查詢時,需要注意將大查詢切分成小查詢,可以減少對數(shù)據(jù)庫的影響,因為一個大語句一次性完成的話,則可能一次鎖住很多數(shù)據(jù),占滿整個事務(wù)日志,耗盡系統(tǒng)資源,阻塞其他查詢。

比如我們做數(shù)據(jù)統(tǒng)計時要對大量訂單號的信息進行查詢,那么是一次性用in查詢,還是切割參數(shù)list多次查詢呢,答案是切割參數(shù)list多次查詢,因為當(dāng)in里面的參數(shù)過多時,MySQL就會認為再走索引已經(jīng)不行了,可能就會進行全表查詢,如果這個時候數(shù)據(jù)表數(shù)據(jù)量過大,那可能就會造成查詢超時。

// chops a list into non-view sublists of length L
static <T> List<List<T>> chopped(List<T> list, final int L) {
    List<List<T>> parts = new ArrayList<List<T>>();
    final int N = list.size();
    for (int i = 0; i < N; i += L) {
        parts.add(new ArrayList<T>(
            list.subList(i, Math.min(N, i + L)))
        );
    }
    return parts;
}
List<Integer> numbers = Collections.unmodifiableList(
    Arrays.asList(5,3,1,2,9,5,0,7)
);
List<List<Integer>> parts = chopped(numbers, 3);
System.out.println(parts); // prints "[[5, 3, 1], [2, 9, 5], [0, 7]]"
parts.get(0).add(-1);
System.out.println(parts); // prints "[[5, 3, 1, -1], [2, 9, 5], [0, 7]]"
System.out.println(numbers); // prints "[5, 3, 1, 2, 9, 5, 0, 7]" (unmodified!)

在程序中將list截斷,從而使查詢能使用索引而不是進行全表掃描。

阿里開發(fā)手冊中就推薦仔細評估in后面的集合元素數(shù)量,控制在1000個之內(nèi)。

分解關(guān)聯(lián)查詢

將多表inner join 進行分解,分解成小查詢,超過三個表的join,就需要禁止了。

優(yōu)點有:

  1. 緩存的效率會更高,

  2. 分解后的查詢可以減少鎖的競爭

  3. 應(yīng)用層可以緩存查詢數(shù)據(jù),減小數(shù)據(jù)庫的壓力。

  4. 可以提升查詢效率,因為用主鍵之類進行in查詢,比按照條件范圍查詢可能會更高效,尤其是大表的時候。

  5. 可以減少冗余記錄的查詢

  6. 更進一步,這樣做相當(dāng)于在應(yīng)用中實現(xiàn)了哈希關(guān)聯(lián),而不是使用MySQL的嵌套循環(huán)關(guān)聯(lián)。某些場景哈希關(guān)聯(lián)的效率要高很多。

到此,關(guān)于“如何利用MySQL進行慢查詢以及重構(gòu)查詢”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

向AI問一下細節(jié)
AI