欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一個 20 秒 SQL 慢查詢優(yōu)化處理方案

 更新時間:2022年01月06日 11:16:20   作者:暗夜在火星  
這篇文章主要分享一個 20 秒 SQL 慢查詢優(yōu)化的經(jīng)歷與處理方案,頁面無法正確獲取數(shù)據(jù),經(jīng)排查原來是接口調(diào)用超時,而最后發(fā)現(xiàn)是因為SQL查詢長達到20多秒而導(dǎo)致了問題的發(fā)生,下面來看問題具體介紹吧

1.背景

頁面無法正確獲取數(shù)據(jù),經(jīng)排查原來是接口調(diào)用超時,而最后發(fā)現(xiàn)是因為SQL查詢長達到20多秒而導(dǎo)致了問題的發(fā)生。
這里,沒有高深的理論或技術(shù),只是備忘一下經(jīng)歷和解讀一些思想誤區(qū)。

2.復(fù)雜SQL語句的構(gòu)成

這里不過多對業(yè)務(wù)功能進行描述,但為了突出問題所在,會用類比的語句來描述當(dāng)時的場景

復(fù)雜的SQL語句可以表達如下:

SELECT * FROM a_table AS a?
LEFT JOIN b_table AS b ON a.id=b.id?
WHERE a.id IN (
SELECT DISTINCT id FROM a_table?
WHERE user_id IN (100,102,103) GROUP BY user_id HAVING count(id) > 3
)

3.關(guān)聯(lián)查詢

從上面簡化的SQL語句,可以看出,首先進行的是關(guān)聯(lián)查詢。

4.子查詢

其次,是嵌套的子查詢。此子查詢是為了找出多個用戶共同擁有的組ID。所以語句中的“100,102,103”是根據(jù)場景來定的,并且需要和后面“count(id) > 3”的個數(shù)對應(yīng)。簡單來說,就是找用戶交集的組ID。

5.耗時在哪?

假設(shè)現(xiàn)在a_table表的數(shù)據(jù)量為20W,而b_table的數(shù)據(jù)量為2000W。大家可以想一下,你覺得主要的耗時是在關(guān)聯(lián)查詢部分,還是在子查詢部分?
(思考空間。。。。)
(思考空間。。。。。。。)
(思考空間。。。。。。。。。。)

6.問題定位

對于SQL底層的原理和高深的理論,我暫時掌握不夠深入。但我知道可以通過類比和簡單的測試來驗證是哪一塊環(huán)節(jié)出了問題。

7.初步斷定

首先,對于只有一個用戶ID時,我會把上面的語句簡化成:

ELECT * FROM a_table AS a?
LEFT JOIN b_table AS b ON a.id=b.id?
WHERE user_id IN (100)

所以,初步斷定應(yīng)該是嵌套的子查詢部分占用了大部分的時間。

9.再進一步驗證

既然定位到了是嵌套的子查詢語句的問題,那又要分為兩塊待排查的區(qū)域:是子查詢本身耗時大,還是嵌套而導(dǎo)致慢查詢?
結(jié)果很容易發(fā)現(xiàn),當(dāng)我把子查詢單獨在DB中執(zhí)行時,是非??斓?。所以排除。
剩下的不言而喻,20秒的慢查詢是嵌套引起的。

但因為處于上線緊急的過程中,為了確保,我快速地驗證了我的結(jié)論:

  • 1、將子查詢的ID單獨執(zhí)行,并把得到的結(jié)果序列手動拼成一段ID,如:1,2,3,4, … , 999
  • 2、將上面得到的序列ID,手動替換到原來的SQL語句
  • 3、執(zhí)行,發(fā)現(xiàn),很快!只用了約150 ms

Well Done!  準(zhǔn)備修復(fù)上線!

10.解決方案

線上的問題,很多時間都是在定位問題和分析原因,既然問題找到了,原因也找到了,解決方案不言而喻。代碼簡單處理即可。

11.另外一個需要注意的點

當(dāng)前,實際的SQL語句,會比這個更為復(fù)雜,但已足以表達問題所在。但在前期,筆者也做了一些SQL的代碼。
因為b_tablea_table大,所以一開始b_table 左關(guān)聯(lián)a_table 時,很慢,大概是1秒多,而且數(shù)據(jù)量是很少的;但若反過來,a_table 左關(guān)聯(lián)b_table 時,則很快,大概是100毫秒。

所以,又發(fā)現(xiàn)一個有趣的現(xiàn)象:

大表 左關(guān)聯(lián) 小表,很慢;小表 左關(guān)聯(lián) 大表,很快。
當(dāng)然,這些我們理論上都知道,但實際開發(fā)會忘卻。又或者一開始兩個表都為空時,而又沒考慮到后期這兩個表增長的速度時,日后就會埋下坑了。

總結(jié):

首先,嵌套的子查詢是很慢的。
原因,我還沒仔細去研究,但在下班的路上和我的同事交流時,他說曾經(jīng)看過這方面相關(guān)的書籍,是說每一次的子查詢都會產(chǎn)生一個SQL語句,所以就N次查詢了。而另外一位資深的QA同事則跟我說,應(yīng)該是M*N的問題。
其次,我一開始使用嵌套子查詢,是存在這樣一個誤區(qū):我覺得將這些操作交給MySQL自身來處理會更高效,畢竟DB內(nèi)部會有良好的機制來執(zhí)行這些查詢由。
然后,實際表白,我錯了。因為這不是簡單的合并MC批量查詢。
當(dāng)我們決定使用一些底層的技術(shù)時,只有當(dāng)我們理解透徹了,才能使用更為恰當(dāng)。而因為無知就斷定工具、框架、底層無所不能時,往往就會中招。

到此這篇關(guān)于一個 20 秒 SQL 慢查詢優(yōu)化的經(jīng)歷與處理方案的文章就介紹到這了,更多相關(guān) SQL 慢查詢優(yōu)化的經(jīng)歷與處理方案內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • MySQL for update鎖表還是鎖行校驗(過程詳解)

    MySQL for update鎖表還是鎖行校驗(過程詳解)

    在MySQL中,使用for update子句可以對查詢結(jié)果集進行行級鎖定,以便在事務(wù)中對這些行進行更新或者防止其他事務(wù)對這些行進行修改,這篇文章主要介紹了MySQL for update鎖表還是鎖行校驗,需要的朋友可以參考下
    2024-02-02
  • MySQL數(shù)據(jù)庫卸載的完整步驟

    MySQL數(shù)據(jù)庫卸載的完整步驟

    這篇文章主要為大家詳細介紹了MySQL數(shù)據(jù)庫卸載的完整步驟,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • 一千行的MySQL學(xué)習(xí)筆記匯總

    一千行的MySQL學(xué)習(xí)筆記匯總

    這篇文章主要介紹了一千行的MySQL學(xué)習(xí)筆記匯總,實例總結(jié)了MySQL學(xué)習(xí)中遇到的各類常見問題與實用技巧,需要的朋友可以參考下
    2014-10-10
  • Mysql刪除數(shù)據(jù)以及數(shù)據(jù)表的方法實例

    Mysql刪除數(shù)據(jù)以及數(shù)據(jù)表的方法實例

    這篇文章主要給大家介紹了關(guān)于Mysql刪除數(shù)據(jù)以及數(shù)據(jù)表的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • Mysql存儲引擎詳解

    Mysql存儲引擎詳解

    存儲引擎其實就是如何實現(xiàn)存儲數(shù)據(jù),如何為存儲的數(shù)據(jù)建立索引以及如何更新,查詢數(shù)據(jù)等技術(shù)實現(xiàn)的方法。本文我們來詳細探討下MySQL中的幾個存儲引擎(MyISAM、InnoDB、archive、MERGE)的相關(guān)知識
    2016-12-12
  • 專業(yè)級的MySQL開發(fā)設(shè)計規(guī)范及SQL編寫規(guī)范

    專業(yè)級的MySQL開發(fā)設(shè)計規(guī)范及SQL編寫規(guī)范

    這篇文章主要介紹了專業(yè)級的MySQL開發(fā)設(shè)計規(guī)范及SQL編寫規(guī)范,需要的朋友可以參考下
    2020-11-11
  • 淺談MySQL之淺入深出頁原理

    淺談MySQL之淺入深出頁原理

    首先,我們需要知道,頁(Pages)是InnoDB中管理數(shù)據(jù)的最小單元。Buffer Pool中存的就是一頁一頁的數(shù)據(jù)。當(dāng)我們要查詢的數(shù)據(jù)不在Buffer Pool中時,InnoDB會將記錄所在的頁整個加載到Buffer Pool中去;同樣,將Buffer Pool中的臟頁刷入磁盤時,也是按照頁為單位刷入磁盤的
    2021-06-06
  • MySQL出現(xiàn)2003錯誤的三種解決方法

    MySQL出現(xiàn)2003錯誤的三種解決方法

    本文主要介紹了MySQL出現(xiàn)2003錯誤的解決方法,主要介紹了3種方法,具有一定的參考價值,感興趣的可以了解一下
    2023-09-09
  • 詳解MySQL的limit用法和分頁查詢語句的性能分析

    詳解MySQL的limit用法和分頁查詢語句的性能分析

    本篇文章主要介紹了詳解MySQL的limit用法和分頁查詢語句的性能分析,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2017-03-03
  • mysql存儲過程之if語句用法實例詳解

    mysql存儲過程之if語句用法實例詳解

    這篇文章主要介紹了mysql存儲過程之if語句用法,結(jié)合實例形式詳細分析了mysql存儲過程中if語句相關(guān)原理、使用技巧與操作注意事項,需要的朋友可以參考下
    2019-12-12

最新評論