色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

一次SQL查詢優(yōu)化原理分析:900W+數(shù)據(jù),從17s到300ms

數(shù)據(jù)分析與開(kāi)發(fā) ? 來(lái)源:未知 ? 2023-04-14 14:27 ? 次閱讀

有一張財(cái)務(wù)流水表,未分庫(kù)分表,目前的數(shù)據(jù)量為9555695,分頁(yè)查詢使用到了limit,優(yōu)化之前的查詢耗時(shí)16 s 938 ms(execution: 16 s 831 ms, fetching: 107 ms),按照下文的方式調(diào)整SQL后,耗時(shí)347 ms(execution: 163 ms, fetching: 184 ms);

操作:查詢條件放到子查詢中,子查詢只查主鍵ID,然后使用子查詢中確定的主鍵關(guān)聯(lián)查詢其他的屬性字段;

原理:減少回表操作,利用延遲關(guān)聯(lián)或者子查詢優(yōu)化超多分頁(yè)場(chǎng)景。

--優(yōu)化前SQL
SELECT各種字段
FROM`table_name`
WHERE各種條件
LIMIT0,10;
--優(yōu)化后SQL
SELECT各種字段
FROM`table_name`main_tale
RIGHTJOIN
(
SELECT子查詢只查主鍵
FROM`table_name`
WHERE各種條件
LIMIT0,10;
)temp_tableONtemp_table.主鍵=main_table.主鍵

找到的原理分析:MySQL 用 limit 為什么會(huì)影響性能?

前言

首先說(shuō)明一下MySQL的版本:

mysql>selectversion();
+-----------+
|version()|
+-----------+
|5.7.17|
+-----------+
1rowinset(0.00sec)

表結(jié)構(gòu):

mysql>desctest;
+--------+---------------------+------+-----+---------+----------------+
|Field|Type|Null|Key|Default|Extra|
+--------+---------------------+------+-----+---------+----------------+
|id|bigint(20)unsigned|NO|PRI|NULL|auto_increment|
|val|int(10)unsigned|NO|MUL|0||
|source|int(10)unsigned|NO||0||
+--------+---------------------+------+-----+---------+----------------+
3rowsinset(0.00sec)

id為自增主鍵,val為非唯一索引

灌入大量數(shù)據(jù),共500萬(wàn):

mysql>selectcount(*)fromtest;
+----------+
|count(*)|
+----------+
|5242882|
+----------+
1rowinset(4.25sec)

我們知道,當(dāng)limit offset rows中的offset很大時(shí),會(huì)出現(xiàn)效率問(wèn)題:

mysql>select*fromtestwhereval=4limit300000,5;
+---------+-----+--------+
|id|val|source|
+---------+-----+--------+
|3327622|4|4|
|3327632|4|4|
|3327642|4|4|
|3327652|4|4|
|3327662|4|4|
+---------+-----+--------+
5rowsinset(15.98sec)

為了達(dá)到相同的目的,我們一般會(huì)改寫(xiě)成如下語(yǔ)句:

mysql>select*fromtestainnerjoin(selectidfromtestwhereval=4limit300000,5)bona.id=b.id;
+---------+-----+--------+---------+
|id|val|source|id|
+---------+-----+--------+---------+
|3327622|4|4|3327622|
|3327632|4|4|3327632|
|3327642|4|4|3327642|
|3327652|4|4|3327652|
|3327662|4|4|3327662|
+---------+-----+--------+---------+
5rowsinset(0.38sec)

時(shí)間相差很明顯。

為什么會(huì)出現(xiàn)上面的結(jié)果?我們看一下select * from test where val=4 limit 300000,5;的查詢過(guò)程:

查詢到索引葉子節(jié)點(diǎn)數(shù)據(jù)。根據(jù)葉子節(jié)點(diǎn)上的主鍵值去聚簇索引上查詢需要的全部字段值。

類似于下面這張圖:45d781ce-d8f7-11ed-bfe3-dac502259ad0.jpg

像上面這樣,需要查詢300005次索引節(jié)點(diǎn),查詢300005次聚簇索引的數(shù)據(jù),最后再將結(jié)果過(guò)濾掉前300000條,取出最后5條。MySQL耗費(fèi)了大量隨機(jī)I/O在查詢聚簇索引的數(shù)據(jù)上,而有300000次隨機(jī)I/O查詢到的數(shù)據(jù)是不會(huì)出現(xiàn)在結(jié)果集當(dāng)中的。

肯定會(huì)有人問(wèn):既然一開(kāi)始是利用索引的,為什么不先沿著索引葉子節(jié)點(diǎn)查詢到最后需要的5個(gè)節(jié)點(diǎn),然后再去聚簇索引中查詢實(shí)際數(shù)據(jù)。這樣只需要5次隨機(jī)I/O,類似于下面圖片的過(guò)程:

45ed9680-d8f7-11ed-bfe3-dac502259ad0.jpg

其實(shí)我也想問(wèn)這個(gè)問(wèn)題。

證實(shí)

下面我們實(shí)際操作一下來(lái)證實(shí)上述的推論:

為了證實(shí)select * from test where val=4 limit 300000,5是掃描300005個(gè)索引節(jié)點(diǎn)和300005個(gè)聚簇索引上的數(shù)據(jù)節(jié)點(diǎn),我們需要知道MySQL有沒(méi)有辦法統(tǒng)計(jì)在一個(gè)sql中通過(guò)索引節(jié)點(diǎn)查詢數(shù)據(jù)節(jié)點(diǎn)的次數(shù)。我先試了Handler_read_*系列,很遺憾沒(méi)有一個(gè)變量能滿足條件。

我只能通過(guò)間接的方式來(lái)證實(shí):

InnoDB中有buffer pool。里面存有最近訪問(wèn)過(guò)的數(shù)據(jù)頁(yè),包括數(shù)據(jù)頁(yè)和索引頁(yè)。所以我們需要運(yùn)行兩個(gè)sql,來(lái)比較buffer pool中的數(shù)據(jù)頁(yè)的數(shù)量。

預(yù)測(cè)結(jié)果是運(yùn)行select * from test a inner join (select id from test where val=4 limit 300000,5);之后,buffer pool中的數(shù)據(jù)頁(yè)的數(shù)量遠(yuǎn)遠(yuǎn)少于select * from test where val=4 limit 300000,5;對(duì)應(yīng)的數(shù)量,因?yàn)榍耙粋€(gè)sql只訪問(wèn)5次數(shù)據(jù)頁(yè),而后一個(gè)sql訪問(wèn)300005次數(shù)據(jù)頁(yè)。

select*fromtestwhereval=4limit300000,5
mysql>selectindex_name,count(*)frominformation_schema.INNODB_BUFFER_PAGEwhereINDEX_NAMEin('val','primary')andTABLE_NAMElike'%test%'groupbyindex_name;Emptyset(0.04sec)

可以看出,目前buffer pool中沒(méi)有關(guān)于test表的數(shù)據(jù)頁(yè)。

mysql>select*fromtestwhereval=4limit300000,5;
+---------+-----+--------+
|id|val|source|
+---------+-----+--------+|
3327622|4|4|
|3327632|4|4|
|3327642|4|4|
|3327652|4|4|
|3327662|4|4|
+---------+-----+--------+
5rowsinset(26.19sec)

mysql>selectindex_name,count(*)frominformation_schema.INNODB_BUFFER_PAGEwhereINDEX_NAMEin('val','primary')andTABLE_NAMElike'%test%'groupbyindex_name;
+------------+----------+
|index_name|count(*)|
+------------+----------+
|PRIMARY|4098|
|val|208|
+------------+----------+2rowsinset(0.04sec)

可以看出,此時(shí)buffer pool中關(guān)于test表有4098個(gè)數(shù)據(jù)頁(yè),208個(gè)索引頁(yè)。

select * from test a inner join (select id from test where val=4 limit 300000,5) ;為了防止上次試驗(yàn)的影響,我們需要清空buffer pool,重啟mysql。

mysqladminshutdown
/usr/local/bin/mysqld_safe&
mysql>selectindex_name,count(*)frominformation_schema.INNODB_BUFFER_PAGEwhereINDEX_NAMEin('val','primary')andTABLE_NAMElike'%test%'groupbyindex_name;

Emptyset(0.03sec)

運(yùn)行sql:

mysql>select*fromtestainnerjoin(selectidfromtestwhereval=4limit300000,5)bona.id=b.id;
+---------+-----+--------+---------+
|id|val|source|id|
+---------+-----+--------+---------+
|3327622|4|4|3327622|
|3327632|4|4|3327632|
|3327642|4|4|3327642|
|3327652|4|4|3327652|
|3327662|4|4|3327662|
+---------+-----+--------+---------+
5rowsinset(0.09sec)

mysql>selectindex_name,count(*)frominformation_schema.INNODB_BUFFER_PAGEwhereINDEX_NAMEin('val','primary')andTABLE_NAMElike'%test%'groupbyindex_name;
+------------+----------+
|index_name|count(*)|
+------------+----------+
|PRIMARY|5|
|val|390|
+------------+----------+
2rowsinset(0.03sec)

我們可以看明顯的看出兩者的差別:第一個(gè)sql加載了4098個(gè)數(shù)據(jù)頁(yè)到buffer pool,而第二個(gè)sql只加載了5個(gè)數(shù)據(jù)頁(yè)到buffer pool。符合我們的預(yù)測(cè)。也證實(shí)了為什么第一個(gè)sql會(huì)慢:讀取大量的無(wú)用數(shù)據(jù)行(300000),最后卻拋棄掉。而且這會(huì)造成一個(gè)問(wèn)題:加載了很多熱點(diǎn)不是很高的數(shù)據(jù)頁(yè)到buffer pool,會(huì)造成buffer pool的污染,占用buffer pool的空間。遇到的問(wèn)題

為了在每次重啟時(shí)確保清空buffer pool,我們需要關(guān)閉innodb_buffer_pool_dump_at_shutdown和innodb_buffer_pool_load_at_startup,這兩個(gè)選項(xiàng)能夠控制數(shù)據(jù)庫(kù)關(guān)閉時(shí)dump出buffer pool中的數(shù)據(jù)和在數(shù)據(jù)庫(kù)開(kāi)啟時(shí)載入在磁盤(pán)上備份buffer pool的數(shù)據(jù)。

審核編輯 :李倩


聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 數(shù)據(jù)
    +關(guān)注

    關(guān)注

    8

    文章

    7134

    瀏覽量

    89403
  • SQL
    SQL
    +關(guān)注

    關(guān)注

    1

    文章

    773

    瀏覽量

    44219
  • 數(shù)據(jù)庫(kù)
    +關(guān)注

    關(guān)注

    7

    文章

    3845

    瀏覽量

    64596

原文標(biāo)題:一次 SQL 查詢優(yōu)化原理分析:900W+ 數(shù)據(jù),從 17s 到 300ms

文章出處:【微信號(hào):DBDevs,微信公眾號(hào):數(shù)據(jù)分析與開(kāi)發(fā)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    文了解MyBatis的查詢原理

    本文通過(guò)MyBatis個(gè)低版本的bug(3.4.5之前的版本)入手,分析MyBatis的一次完整的查詢流程,配置文件的解析
    的頭像 發(fā)表于 10-10 11:42 ?1460次閱讀

    ADS1232信號(hào)輸入零點(diǎn)滿度兩點(diǎn)變化,其數(shù)據(jù)建立過(guò)程需要兩轉(zhuǎn)換,為什么?

    ADS1232信號(hào)輸入零點(diǎn)滿度兩點(diǎn)變化(用的是信號(hào)模擬器),發(fā)現(xiàn)其數(shù)據(jù)建立過(guò)程需要兩
    發(fā)表于 01-10 08:02

    基于索引的SQL語(yǔ)句優(yōu)化之降龍十八掌

    的范圍信息會(huì)放入Oracle的數(shù)據(jù)字典中。Oracle可以利用這個(gè)信息來(lái)提取出那些只與SQL查詢相關(guān)的數(shù)據(jù)分區(qū)。例如,假設(shè)你已經(jīng)定義了個(gè)分
    發(fā)表于 09-25 13:24

    2017雙11技術(shù)揭秘—TDDL/DRDS 的類 KV 查詢優(yōu)化實(shí)踐

    僅在SQL層面進(jìn)行進(jìn)優(yōu)化會(huì)非常困難,因此針對(duì)這類場(chǎng)景,TDDL/DRDS 配合 AliSQL 提出了全新的解決方案。作者:勵(lì)強(qiáng)(君瑜)場(chǎng)景介紹性能優(yōu)化是企業(yè)級(jí)應(yīng)用永恒的話題,關(guān)系型
    發(fā)表于 12-29 14:29

    CC2530 廣播 300ms以下就會(huì)產(chǎn)生發(fā)送失敗問(wèn)題,失敗原因:zBufferFull

    多次測(cè)試發(fā)現(xiàn)芯片在廣播的時(shí)候發(fā)送時(shí)間短于300ms一次的話就會(huì)產(chǎn)生發(fā)送失敗的現(xiàn)象,每9失敗幾次,失敗的原因?yàn)閦BufferFull,而采用單播發(fā)送頻率在30ms以下才會(huì)產(chǎn)生丟包問(wèn)題,
    發(fā)表于 06-01 00:38

    SQL查詢慢的原因分析總結(jié)

    sql 查詢慢的48個(gè)原因分析 1、沒(méi)有索引或者沒(méi)有用到索引(這是查詢慢最常見(jiàn)的問(wèn)題,是程序設(shè)計(jì)的缺陷)。 2、I/O吞吐量小,形成了瓶頸效應(yīng)。 3、沒(méi)有創(chuàng)建計(jì)算列導(dǎo)致
    發(fā)表于 03-08 11:58 ?0次下載

    基于關(guān)系代數(shù)樹(shù)的查詢優(yōu)化方法實(shí)例分析

    提出了基于關(guān)系代數(shù)樹(shù)結(jié)構(gòu)的SQL查詢優(yōu)化策略。利用改進(jìn)查詢計(jì)劃的代數(shù)定律,分析基于關(guān)系代數(shù)樹(shù)的關(guān)系代數(shù)式
    發(fā)表于 05-07 10:11 ?21次下載
    基于關(guān)系代數(shù)樹(shù)的<b class='flag-5'>查詢</b><b class='flag-5'>優(yōu)化</b>方法實(shí)例<b class='flag-5'>分析</b>

    基于KingView的SQL數(shù)據(jù)查詢設(shè)計(jì)_楊洋

    基于KingView的SQL數(shù)據(jù)查詢設(shè)計(jì)_楊洋
    發(fā)表于 01-17 19:57 ?0次下載

    企業(yè)海量數(shù)據(jù)查詢優(yōu)化

    查詢分析、統(tǒng)計(jì)操作所基于的SELECT語(yǔ)句在SQL語(yǔ)句中又是付出資源代價(jià)最大的語(yǔ)句。舉個(gè)具體的例子,比如個(gè)數(shù)據(jù)庫(kù)表有上百萬(wàn)甚至上千萬(wàn)條記
    發(fā)表于 12-14 16:40 ?8次下載

    SQL優(yōu)化器原理 - 查詢優(yōu)化器綜述

    摘要:?本文主要是對(duì)數(shù)據(jù)庫(kù)查詢優(yōu)化器的個(gè)綜述,包括查詢優(yōu)化器分類、
    發(fā)表于 07-24 17:38 ?330次閱讀
    <b class='flag-5'>SQL</b><b class='flag-5'>優(yōu)化</b>器原理 - <b class='flag-5'>查詢</b><b class='flag-5'>優(yōu)化</b>器綜述

    SQL查詢優(yōu)化是怎么回事

    查詢 (Subquery)的優(yōu)化直以來(lái)都是 SQL 查詢優(yōu)化中的難點(diǎn)之
    的頭像 發(fā)表于 02-01 13:55 ?2084次閱讀
    <b class='flag-5'>SQL</b>子<b class='flag-5'>查詢</b><b class='flag-5'>優(yōu)化</b>是怎么回事

    SQL優(yōu)化思路與經(jīng)典案例分析

    如何定位慢SQL呢、我們可以通過(guò)慢查詢日志來(lái)查看慢SQL。默認(rèn)的情況下呢,MySQL數(shù)據(jù)庫(kù)是不開(kāi)啟慢查詢日志(slow query log)
    的頭像 發(fā)表于 10-27 13:16 ?959次閱讀

    文終結(jié)SQL查詢優(yōu)化

    查詢(Subquery)的優(yōu)化直以來(lái)都是 SQL 查詢優(yōu)化中的難點(diǎn)之
    的頭像 發(fā)表于 04-28 14:19 ?793次閱讀
    <b class='flag-5'>一</b>文終結(jié)<b class='flag-5'>SQL</b>子<b class='flag-5'>查詢</b><b class='flag-5'>優(yōu)化</b>

    Oracle長(zhǎng)耗時(shí)SQL優(yōu)化案例

    最近在生產(chǎn)客服平臺(tái),運(yùn)營(yíng)崗老師反饋,個(gè)2w人的企業(yè),在信息詳情查詢時(shí),加載時(shí)間過(guò)長(zhǎng),越70s左右出結(jié)果,需要后臺(tái)優(yōu)化
    的頭像 發(fā)表于 05-19 15:02 ?1076次閱讀

    oracle執(zhí)行sql查詢語(yǔ)句的步驟是什么

    Oracle數(shù)據(jù)庫(kù)是種常用的關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng),具有強(qiáng)大的SQL查詢功能。Oracle執(zhí)行SQL
    的頭像 發(fā)表于 12-06 10:49 ?1025次閱讀
    主站蜘蛛池模板: 成人国产亚洲欧美成人综合网 | 国产产一区二区三区久久毛片国语 | 国产香蕉视频在线观看 | 青青国产在线观看视频 | 国产成人精品免费青青草原app | 成人免费在线观看 | 国产一区二区三区影院 | 麻豆第一区MV免费观看网站 | 精品国产国产综合精品 | 国产中文字幕免费观看 | 99热国产这里只有精品9九 | 57PAO强力打造高清免费 | 亚欧洲乱码视频一二三区 | 狠狠色丁香婷婷久久综合五月 | 亚洲中字幕永久在线观看 | 扒开粉嫩的小缝末成年小美女 | 久久精品国产男包 | 浓毛BWBWBWBWBW日本 | 青青视频 在线 在线播放 | 狠狠啪 日日啪 | 99久久久无码国产AAA精品 | 色婷婷国产精品视频一区二区三区 | 成人高清护士在线播放 | 免费中文字幕视频 | 青青青草免费 | 国产欧美日韩精品a在线观看高清 | 国产九九熟女在线视频 | 麻豆免费观看高清完整视频在线 | 欧洲-级毛片内射八十老太婆 | 竹菊影视一区二区三区 | 久久国产精品免费A片蜜芽 久久国产精品萌白酱免费 久久国产精品麻豆AV影视 | 精品国产自在自线官方 | 中国农民真实bbwbbw | 狠狠久久免费视频在线 | 91伊人久久大香线蕉 | 最新精品学生国产自在现拍 | 久久大胆视频 | 别插我B嗯啊视频免费 | 精品国产手机视频在在线 | 同居了嫂子在线观看 | 国产精品18久久久久久欧美网址 |