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

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

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

1.背景

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

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

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

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

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)查詢

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

4.子查詢

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

5.耗時(shí)在哪?

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

6.問題定位

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

7.初步斷定

首先,對(duì)于只有一個(gè)用戶ID時(shí),我會(huì)把上面的語句簡(jiǎn)化成:

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

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

9.再進(jìn)一步驗(yàn)證

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

但因?yàn)樘幱谏暇€緊急的過程中,為了確保,我快速地驗(yàn)證了我的結(jié)論:

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

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

10.解決方案

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

11.另外一個(gè)需要注意的點(diǎn)

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

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

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

總結(jié):

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

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

相關(guān)文章

  • 基于mysql查詢語句的使用詳解

    基于mysql查詢語句的使用詳解

    本篇文章是對(duì)mysql查詢語句的使用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • 用HAProxy來檢測(cè)MySQL復(fù)制的延遲的教程

    用HAProxy來檢測(cè)MySQL復(fù)制的延遲的教程

    這篇文章主要介紹了用HAProxy來檢測(cè)MySQL復(fù)制的延遲的教程,HAProxy需要使用到PHP腳本,需要的朋友可以參考下
    2015-04-04
  • MySQL中create table as 與like的區(qū)別分析

    MySQL中create table as 與like的區(qū)別分析

    這篇文章主要介紹了MySQL中create table as 與like的區(qū)別,結(jié)合實(shí)例分析了二者在使用中的具體區(qū)別與主要用途,需要的朋友可以參考下
    2016-01-01
  • MySQL最基本的命令使用匯總

    MySQL最基本的命令使用匯總

    這篇文章為大家分享了MySQL最基本的命令使用匯總,MySQL最基本的命令使用,包括如何正確連接MySQL(和PHP搭配之最佳組合),修改密碼與增加新用戶等相關(guān)內(nèi)容的描述,感興趣的小伙伴們可以參考一下
    2015-11-11
  • MYSQL拒絕訪問報(bào)錯(cuò)not allowed to connect

    MYSQL拒絕訪問報(bào)錯(cuò)not allowed to connect

    MYSQL拒絕訪問報(bào)錯(cuò)not allowed to connect,下面有個(gè)可行的方法,可以在其它任何的主機(jī)上以root身份登錄
    2014-07-07
  • MySQL之MHA高可用配置及故障切換實(shí)現(xiàn)詳細(xì)部署步驟

    MySQL之MHA高可用配置及故障切換實(shí)現(xiàn)詳細(xì)部署步驟

    這篇文章主要介紹了MySQL之MHA高可用配置及故障切換實(shí)現(xiàn)詳細(xì)部署步驟,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • 全面解析MySQL中的隔離級(jí)別

    全面解析MySQL中的隔離級(jí)別

    這篇文章主要介紹了MySQL中的隔離級(jí)別的相關(guān)資料,幫助大家更好的理解和使用MySQL,感興趣的朋友可以了解下。
    2021-01-01
  • MySQL數(shù)據(jù)庫表的合并及分區(qū)方式

    MySQL數(shù)據(jù)庫表的合并及分區(qū)方式

    這篇文章主要介紹了MySQL數(shù)據(jù)庫表的合并及分區(qū)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • mysql中主鍵索引和聯(lián)合索引的原理與區(qū)別

    mysql中主鍵索引和聯(lián)合索引的原理與區(qū)別

    索引是幫助MySQL高效獲取數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu),本文主要介紹了mysql中主鍵索引和聯(lián)合索引的原理與區(qū)別,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-04-04
  • MySQL如何防止SQL注入并過濾SQL中注入的字符

    MySQL如何防止SQL注入并過濾SQL中注入的字符

    SQL注入是指在輸入?yún)?shù)中添加一些特殊字符(例如單引號(hào)),使輸入的語句成為一段單獨(dú)的可執(zhí)行的SQL語句,這篇文章主要給大家介紹了關(guān)于MySQL如何防止SQL注入并過濾SQL中注入字符的相關(guān)資料,需要的朋友可以參考下
    2024-02-02

最新評(píng)論

贡嘎县| 通化市| 和平区| 孙吴县| 陕西省| 涪陵区| 乐安县| 商南县| 钟祥市| 盈江县| 玉环县| 洛南县| 九江市| 疏附县| 石楼县| 大足县| 纳雍县| 鹤岗市| 新建县| 松滋市| 永福县| 康定县| 西贡区| 安丘市| 镇安县| 乌兰县| 安达市| 交口县| 衢州市| 句容市| 郎溪县| 宁陵县| 宜阳县| 华容县| 蕉岭县| 应城市| 宜阳县| 常熟市| 循化| 固始县| 柘荣县|