chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

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

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

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

MySQL用limit為什么會(huì)影響性能

Linux愛好者 ? 來源:簡書 ? 作者:Muscleape ? 2022-06-20 16:31 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

有一張財(cái)務(wù)流水表,未分庫分表,目前的數(shù)據(jù)量為9555695,分頁查詢使用到了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ō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ì)影響性能?

前言

首先說明一下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萬:

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

我們知道,當(dāng)limit offset rows中的offset很大時(shí),會(huì)出現(xià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ì)改寫成如下語句:

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;的查詢過程:

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

類似于下面這張圖:fdbcabee-efc7-11ec-ba43-dac502259ad0.jpg

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

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

fdd667fa-efc7-11ec-ba43-dac502259ad0.jpg

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

證實(shí)

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

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

我只能通過間接的方式來證實(shí):

InnoDB中有buffer pool。里面存有最近訪問過的數(shù)據(jù)頁,包括數(shù)據(jù)頁和索引頁。所以我們需要運(yùn)行兩個(gè)sql,來比較buffer pool中的數(shù)據(jù)頁的數(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ù)頁的數(shù)量遠(yuǎn)遠(yuǎn)少于select * from test where val=4 limit 300000,5;對(duì)應(yīng)的數(shù)量,因?yàn)榍耙粋€(gè)sql只訪問5次數(shù)據(jù)頁,而后一個(gè)sql訪問300005次數(shù)據(jù)頁。

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中沒有關(guān)于test表的數(shù)據(jù)頁。

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ù)頁,208個(gè)索引頁。

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ù)頁到buffer pool,而第二個(gè)sql只加載了5個(gè)數(shù)據(jù)頁到buffer pool。符合我們的預(yù)測(cè)。也證實(shí)了為什么第一個(gè)sql會(huì)慢:讀取大量的無用數(shù)據(jù)行(300000),最后卻拋棄掉。而且這會(huì)造成一個(gè)問題:加載了很多熱點(diǎn)不是很高的數(shù)據(jù)頁到buffer pool,會(huì)造成buffer pool的污染,占用buffer pool的空間。

遇到的問題

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

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

文章出處:【微信公眾號(hào):Linux愛好者】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

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

    關(guān)注

    8

    文章

    7314

    瀏覽量

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

    關(guān)注

    1

    文章

    789

    瀏覽量

    46329
  • MySQL
    +關(guān)注

    關(guān)注

    1

    文章

    897

    瀏覽量

    29191

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

文章出處:【微信號(hào):LinuxHub,微信公眾號(hào):Linux愛好者】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    MySQL 8.0性能優(yōu)化實(shí)戰(zhàn)指南

    作為一名運(yùn)維工程師,MySQL數(shù)據(jù)庫優(yōu)化是我們?nèi)粘9ぷ髦凶罹咛魬?zhàn)性的任務(wù)之一。MySQL 8.0作為當(dāng)前主流版本,在性能、安全性和功能上都有了顯著提升,但如何充分發(fā)揮其潛力,仍需要我們掌握正確的優(yōu)化策略。
    的頭像 發(fā)表于 07-24 11:48 ?519次閱讀

    MySQL數(shù)據(jù)備份與恢復(fù)策略

    數(shù)據(jù)是企業(yè)的核心資產(chǎn),MySQL作為主流的關(guān)系型數(shù)據(jù)庫管理系統(tǒng),其數(shù)據(jù)的安全性和可靠性至關(guān)重要。本文將深入探討MySQL的數(shù)據(jù)備份策略、常用備份工具以及數(shù)據(jù)恢復(fù)的最佳實(shí)踐,幫助運(yùn)維工程師構(gòu)建完善的數(shù)據(jù)保護(hù)體系。
    的頭像 發(fā)表于 07-14 11:11 ?453次閱讀

    企業(yè)級(jí)MySQL數(shù)據(jù)庫管理指南

    在當(dāng)今數(shù)字化時(shí)代,MySQL作為全球最受歡迎的開源關(guān)系型數(shù)據(jù)庫,承載著企業(yè)核心業(yè)務(wù)數(shù)據(jù)的存儲(chǔ)與處理。作為數(shù)據(jù)庫管理員(DBA),掌握MySQL的企業(yè)級(jí)部署、優(yōu)化、維護(hù)技能至關(guān)重要。本文將從實(shí)戰(zhàn)角度出發(fā),系統(tǒng)闡述MySQL在企業(yè)環(huán)
    的頭像 發(fā)表于 07-09 09:50 ?494次閱讀

    除了增刪改查你對(duì)MySQL還了解多少

    我們都知道MySQL服務(wù)器的默認(rèn)端口為3306,之后就在這個(gè)端口號(hào)上等待客戶端進(jìn)程進(jìn)行連接(MySQL服務(wù)器會(huì)默認(rèn)監(jiān)聽3306端口)。
    的頭像 發(fā)表于 04-14 17:20 ?500次閱讀

    適用于MySQL的dbExpress驅(qū)動(dòng)程序:提供對(duì)MySQL的快速訪問

    dbExpress Driver for MySQL 概述 dbExpress 是一個(gè)獨(dú)立于數(shù)據(jù)庫的層,它定義了通用接口以提供 在 Windows 上從 Delphi 和 C++ Builder
    的頭像 發(fā)表于 01-21 09:52 ?661次閱讀

    從Delphi、C++ Builder和Lazarus連接到MySQL數(shù)據(jù)庫

    ? 從 Delphi、C++ Builder 和 Lazarus 連接到 MySQL 數(shù)據(jù)庫 MySQL 數(shù)據(jù)訪問組件(MyDAC)是一個(gè)組件庫,提供從 Delphi 和 C++ Builder
    的頭像 發(fā)表于 01-20 13:47 ?1296次閱讀
    從Delphi、C++ Builder和Lazarus連接到<b class='flag-5'>MySQL</b>數(shù)據(jù)庫

    使用插件將Excel連接到MySQL/MariaDB

    使用插件將 Excel 連接到 MySQL/MariaDB 適用于 MySQL 的 Devart Excel 插件允許您將 Microsoft Excel 連接到 MySQL 或 MariaDB
    的頭像 發(fā)表于 01-20 12:38 ?1116次閱讀
    使用插件將Excel連接到<b class='flag-5'>MySQL</b>/MariaDB

    適用于MySQL和MariaDB的Python連接器:可靠的MySQL數(shù)據(jù)連接器和數(shù)據(jù)庫

    適用于 MySQL 和 MariaDB 的 Python 連接器 Python Connector for MySQL 是一種可靠的連接解決方案,用于從 Python 應(yīng)用程序訪問 MySQL
    的頭像 發(fā)表于 01-17 12:18 ?834次閱讀
    適用于<b class='flag-5'>MySQL</b>和MariaDB的Python連接器:可靠的<b class='flag-5'>MySQL</b>數(shù)據(jù)連接器和數(shù)據(jù)庫

    使用 sysbench 對(duì) Flexus X 實(shí)例對(duì) mysql 進(jìn)行性能測(cè)評(píng)

    計(jì)算能力的需求而設(shè)計(jì)。該實(shí)例不僅具備卓越的硬件性能,還深度集成了對(duì) MySQL 等數(shù)據(jù)庫的優(yōu)化支持,為用戶提供了卓越的數(shù)據(jù)庫應(yīng)用體驗(yàn)。官網(wǎng)如下: Flexus云服務(wù)器X實(shí)例-華為云Flexus云服務(wù)器X實(shí)例(Flexus X)是柔性算力,六倍
    的頭像 發(fā)表于 01-17 09:18 ?940次閱讀
    使用 sysbench 對(duì) Flexus X 實(shí)例對(duì) <b class='flag-5'>mysql</b> 進(jìn)行<b class='flag-5'>性能</b>測(cè)評(píng)

    適用于MySQL和MariaDB的.NET連接器

    支持 ORM 的適用于 MySQL 和 MariaDB 的 .NET 連接器 dotConnect for MySQL 是一種高性能 ADO.NET 數(shù)據(jù)提供程序,可在開發(fā) MySQL
    的頭像 發(fā)表于 01-16 14:17 ?782次閱讀
    適用于<b class='flag-5'>MySQL</b>和MariaDB的.NET連接器

    適用于MySQL的ODBC驅(qū)動(dòng)程序:可與多個(gè)第三方工具兼容的數(shù)據(jù)連接器

    適用于 MySQL 和 MariaDB 的 ODBC 驅(qū)動(dòng)程序 Devart ODBC Driver for MySQL 是一種高性能連接解決方案,具有企業(yè)級(jí)功能,可用于從 32 位和 64 位
    的頭像 發(fā)表于 01-16 10:12 ?999次閱讀

    MySQL數(shù)據(jù)庫的安裝

    MySQL數(shù)據(jù)庫的安裝 【一】各種數(shù)據(jù)庫的端口 MySQL :3306 Redis :6379 MongoDB :27017 Django :8000 flask :5000 【二】MySQL 介紹
    的頭像 發(fā)表于 01-14 11:25 ?842次閱讀
    <b class='flag-5'>MySQL</b>數(shù)據(jù)庫的安裝

    華為云 Flexus X 實(shí)例 MySQL 性能加速評(píng)測(cè)及對(duì)比

    基于 sysbench 構(gòu)造測(cè)試表和測(cè)試數(shù)據(jù) 12 3.5 數(shù)據(jù)庫讀寫性能測(cè)試 13 四、業(yè)界 U?系列無加速 MySQL 測(cè)
    的頭像 發(fā)表于 12-25 17:10 ?836次閱讀
    華為云 Flexus X 實(shí)例 <b class='flag-5'>MySQL</b> <b class='flag-5'>性能</b>加速評(píng)測(cè)及對(duì)比

    Flexus X 實(shí)例搭配華為云 EulerOS,快速部署 MySQL 并執(zhí)行讀寫性能測(cè)試

    社區(qū) openEuler 構(gòu)建的 linux 操作系統(tǒng),提供云原生、高性能、安全穩(wěn)定的執(zhí)行環(huán)境來開發(fā)和運(yùn)行應(yīng)用程序,助力企業(yè)客戶快速上云及開發(fā)者創(chuàng)新 MySQL 安裝與啟動(dòng) 原計(jì)劃是通過指
    的頭像 發(fā)表于 12-24 12:27 ?946次閱讀
    Flexus X 實(shí)例搭配華為云 EulerOS,快速部署 <b class='flag-5'>MySQL</b> 并執(zhí)行讀寫<b class='flag-5'>性能</b>測(cè)試

    云服務(wù)器 Flexus X 實(shí)例 MySQL 應(yīng)用加速測(cè)試

    文章目錄 目錄 文章目錄 ? 購買配置 ? 基本配置參考如下: ? 連接服務(wù)器 ? 查詢MySQL狀態(tài) ? 啟動(dòng)MySQL ? 添加配置 ? 添加密碼并修改權(quán)限 ? 性能測(cè)試 ? C#插入數(shù)據(jù)測(cè)試
    的頭像 發(fā)表于 12-24 12:19 ?784次閱讀
    云服務(wù)器 Flexus X 實(shí)例 <b class='flag-5'>MySQL</b> 應(yīng)用加速測(cè)試