MySQL 調優:查詢慢除了索引還能因為什么?

文章目錄

    • 情況一:連接數過小
    • 情況二:Buffer Pool 太小

MySQL 查詢慢除了索引還能因為什么?MySQL 查詢慢,我們一般也會想到是因為索引,但除了索引還有哪些原因會導致數據庫查詢變慢呢?

以下以 MySQL 中一條 SQL 的執行流程為基礎,分析 MySQL 查詢慢除了索引還有哪些原因。

當 MySQL 中一條查詢 SQL 在實際進入影響 SQL 執行效率的流程前(主要是優化器流程與執行器流程),首先會進入分析器流程。以 Python 進程為例,以下舉例一條 MySQL 語句執行下來會經歷哪些流程。

例如在 MySQL 中有一張名為 use_info 的數據表,一個 Python 進程嘗試攜帶賬號密碼等信息嘗試向 MySQL 建立一條網絡連接,而 MySQL 的連接管理模塊會對這條連接進行管理。

在連接被建立后,Python 應用嘗試向 MySQL 服務器執行如下 SQL 查詢語句:

SELECT user_name,user_address FROM user_info where user_id = 1;

此時 Python 進程需要將 SQL 語句通過網絡連接給 MySQL,MySQL 收到 SQL 語句后將在分析器中先判斷一下 SQL 語句有沒有語法錯誤。例如 SELECT 是否少寫個 L:

SEECT user_name,user_address FROM user_info where user_id = 1;

如果 SQL 錯誤,SELECT 中確實少寫個 L,將拋出相關的異常提示:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SEECT user_name,user_address FROM user_info where user_id = 1' at line 1

SQL 在分析器過程中執行無誤后將到達優化器,而優化器會根據一些規則選擇需要使用的索引,之后執行器會調用存儲引擎的接口函數,MySQL 中的存儲引擎是MySQL 中真正負責讀寫數據的組件。在如今的 MySQL 數據庫開發中,最常用的存儲引擎就是 InnoDB 存儲引擎。

由于讀寫磁盤較慢,所以 InnoDB 存儲引擎內部增加了一層名為 Buffer Pool 的內存提速設計, 在 Buffer Pool 中即存放行數據又存放索引數據。查詢 SQL 到了 InnoDB 中會根據前面優化器里計算得到的索引去查詢相應的索引頁,如果索引頁不在 Buffer Pool 里,則從磁盤里加載到索引頁,再通過索引頁查詢得到數據頁的位置。如果這些數據頁不在 Buffer Pool 中,則從磁盤里加載進來,最后將得到的一行行數據結果返回給客戶端。

在優化器流程與執行器流程過程中,數據庫慢查詢一般是優化器選錯索引導致。這類問題可以通過 EXPLAIN 命令排查。

但是,除了索引之外,還有哪些因素會限制查詢速度呢?

情況一:連接數過小

MySQL 的連接管理模塊作用是管理客戶端和 MySQL 之間的長連接,假設兩者之間只有一條連接,那么在執行 SQL 查詢之后只能阻塞等待結果返回,如果有大量查詢同時并發請求,那么后面的請求都需要等待前面的請求執行完成后才能開始執行。因此有時候從應用程序的日志看,有些 SQL 執行了幾分鐘,但將 SQL 單獨拎出來執行卻只有幾毫秒的情況。對于這種情況,實際上就是因為這些 SQL 語句在等待前面的 SQL 執行完成。

那么這個問題該如何解決呢?其實多建立一些連接就可以解決這個問題,多建一些連接目的是讓請求能夠并發執行,從而使后面的連接不需要等待那么久。但需要注意的是,連接數過小的問題受數據庫和客戶端兩側同時限制。

  • 數據庫連接數過小的情況:

    MySQL 的最大連接數默認是100,最大可以達到 16384,可以通過如下命令將 SQL 的最大連接數改為500。

    SET GLOBAL max_connections = 500;
    

    查看 MySQL 最大連接數配置命令:

    SHOW GLOBAL VARIABLES LIKE 'max_connections';
    
  • 應用側連接數過小的情況:

    如果數據庫連接大小是調整過了,但卻沒啥效果,那可能是因為服務應用(如 Java 或 Python 應用等)的連接數也過小。應用側與 MySQL 底層的連接是基于 TCP 協議的長連接,而建立長連接比較耗時,所以通常情況下會維護一個長連接池,要執行 SQL 時從里面撈出一條連接出來用,用完塞回去,下次復用。

    需要注意的是,連接池的容量會有上限,連接池容量的上限指的是連接池能夠控制的連接數量,如果連接池容量的上限太低,那么修改連接池最大連接數也沒什么作用。

    如果需要調大這個連接池該如何調呢?在實際編碼中,通常服務應用(如 Java 或 Python 應用等)都會通過 ORM 庫進行讀寫操作,而成熟的 ORM 庫會有個連接池的配置,按照官方文檔改就好。

情況二:Buffer Pool 太小

Buffer Pool 太小也會導致 MySQL 查詢慢的問題。在前文提到的 InnoDB 存儲引擎中里有一層內存 Buffer Pool,Buffer Pool 通過緩存磁盤數據用于加速查詢,如果 Buffer Pool 越大,那么 Buffer Pool 中能夠存放的數據頁就越多,相應的 SQL 查詢時就更可能命中 Buffer Pool,那么 MySQL 查詢速度自然更快。

可以執行下面命令增大 Buffer Pool 的大小:

SET GLOBAL innodb_buffer_pool_size = 536870912;

innodb_buffer_pool_size 是 MySQL 中用于設置 Buffer Pool 的參數,它的單位為字節。上例中,將 innodb_buffer_pool_size 的值設置為 536870912 即將將 InnoDB 緩沖池的大小為 536870912 字節,換算成兆字節(MB)為 521 MB(因為 1 MB = 1024 * 1024 個字節)。

查詢 innodb_buffer_pool_size 的大小命令:

SHOW GLOBAL VARIABLES LIKE 'innodb_buffer_pool_size';

輸出的結果例如:

在這里插入圖片描述

但是如果數據庫查詢慢并不是由于 Buffer Pool 的大小導致,那么修改 Buffer Pool 的大小就毫無意義。那么如何判斷 Buffer Pool 是不是太小了?可以通過查看 Buffer Pool 的命中率來分析。

可以通過如下命令查詢 Buffer Pool 的一些相關信息:

SHOW STATUS LIKE 'Innodb_buffer_pool_%';

得到的 Buffer Pool 相關信息例如:

在這里插入圖片描述

其中 Innodb_buffer_pool_read_requests 表示請求的次數,Innodb_buffer_pool_reads 表示從物理磁盤中讀數據的請求次數。

Buffer Pool 的命中率可以通過如下公式計算:

1-(Innodb_buffer_pool_reads/Innodb_buffer_pool_read_requests)*100%

例如上述 Buffer Pool 的命中率為:

1-(68759212/4966742025)*100% ≈ 98.6156%

一般情況下,Buffer Pool 的命中率都在 99% 以上,如果低于 99% 才需要考慮加大 Buffer Pool 的大小。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/73399.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/73399.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/73399.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【操作系統】進程三種狀態?進程間狀態的切換?掛起態?

進程狀態 進程的五種(三種)狀態: 新建(New):進程剛被創建,尚未加入到就緒隊列;就緒(Ready):進程已獲得除CPU外的所有資源,等待被調度執…

計算機控制系統的最小拍控制器設計及仿真分析

1題目 開環傳遞函數 G(s) 2/(s(0.5s1)) ,采樣周期 T0.5 秒,設計單位速度輸入下的最小拍控制器 1.1 方法1 根據課本中的步驟,最小拍控制器的設計步驟如下: 1. 確定對象的離散傳遞函數G(z),并確定其零極點。 2. 確定…

哈希--哈希桶

哈希桶是哈希表(散列表)中的一個概念,是哈希表數組中的每個元素 ,用于存儲鍵值對數據。它有以下特點和相關要點: 結構與原理:哈希表底層常由數組構成,數組的每個元素即哈希桶。通過哈希函數計算…

Linux多線程詳解

Linux多線程詳解 一、Linux多線程概念1.1 什么是線程1.2 進程和線程1.3 進程的多個線程共享1.4 進程和線程的關系 二、Linux線程控制2.1 POSIX線程庫2.2 線程創建2.3 獲取線程ID pthread_self2.4 線程等待pthread_join2.5 線程終止2.6 線程棧 && pthread_t2.7 線程的局…

Midscene.js自然語言驅動的網頁自動化全指南

一、概述 網頁自動化在數據抓取、UI 測試和業務流程優化中發揮著重要作用。然而,傳統工具如 Selenium 和 Puppeteer 要求用戶具備編程技能,編寫復雜的選擇器和腳本維護成本高昂。Midscene.js 通過自然語言接口革新了這一領域,用戶只需描述任…

winstart.wsf 病毒清理大作戰

0x00 背景 發現感染了winstart.wsf 病毒如何清理。 0x01 現象 遍歷Users下每個目錄以及C:\和C:\Windows\Temp 2個目錄寫入病毒文件。 C:\Users\Administrator\AppData\Local\Temp\winstart.wsf C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\Start Menu\Program…

多路轉接Poll

在之前我們講過select是最古老的多路轉接方案,古老就意味著他不是很方便使用,他需要用戶手動保存fd_set這個位圖結構,來表示讀寫事件的關注與否或者就緒性。 而且由于fd_set的大小是固定的,這就意味著他能管理的套接字文件描述符是…

多層感知機的簡潔實現

《動手學深度學習》-4.3-筆記 import torch from torch import nn from d2l import torch as d2l 導入必要的庫和模塊 net nn.Sequential(nn.Flatten(),nn.Linear(784, 256),nn.ReLU(),nn.Linear(256, 10))def init_weights(m):if type(m) nn.Linear:nn.init.normal_(m.we…

【GoLang】調用llm時提示詞prompt的介紹以及使用方式

介紹 提示詞是一種與大模型交互的對話格式,它以 JSON 格式定義了一個消息列表(messages),包含了系統消息和用戶消息。 我們向AI提問時,其實發給AI的都是提示詞,別看我們只是簡單輸入了一句話,…

內核編程十二:打印task_struct中的數據

在Linux內核中,current 是一個宏,用于獲取當前正在執行的進程的 task_struct 結構體指針。current 宏返回一個指向當前正在運行的進程的 task_struct 結構體的指針。通過這個指針,內核代碼可以訪問和修改當前進程的各種屬性和狀態。 打印單個…

區間端點(java)(貪心問題————區間問題)

deepseek給了一種超級簡單的做法 我是真的想不到 貪心的思路是 局部最優——>全局最優 這種我是真的沒有想到,這樣的好處就是后面便利的時候可以通過foreach循環直接便利qu的子元素也就是對應的某一個區間, 將一個二維數組變成一維數組,每一個一維…

Qt事件處理(處理鼠標事件、鍵盤事件、定時器事件、窗口移動和大小變化事件)

事件處理 事件是應用程序內部或者外部產生的事情或者動作的統稱。 在 Qt 中,事件是用一個對象來管理一個事件的。所有的事件對象都繼承自抽象類 QEvent 。事件包括鼠標事件、鍵盤事件等,發出自 Qt 或操作系統本身。 處理事件一般通過重寫相關的 Event 函…

Apache Hive:基于Hadoop的分布式數據倉庫

Apache Hive 是一個基于 Apache Hadoop 構建的開源分布式數據倉庫系統,支持使用 SQL 執行 PB 級大規模數據分析與查詢。 主要功能 Apache Hive 提供的主要功能如下。 HiveServer2 HiveServer2 服務用于支持接收客戶端連接和查詢請求。 HiveServer2 支持多客戶端…

利用 @eslint/eslintrc 實現 ESLint9的適配

深度解析:利用 eslint/eslintrc 實現 ESLint 的高效配置管理 在前端開發領域,代碼質量和一致性是至關重要的。ESLint 作為一款流行的代碼檢查工具,幫助開發者發現代碼中的潛在問題并保持代碼風格的一致性。而隨著項目的復雜度增加和團隊規模…

cfca 申請國密證書流程

之前給某銀行開發項目,需要用到cfca國密雙證證書,證書類型為企業雙證的作為接口加密的密鑰。 因為是第一次對接,其中走了不少的彎路,現將申請的流程發布出來做下記錄 1、需要找到cfca的相關人員進行測試證書的申請 2、大概1天的…

基于Spring Boot的鄉村養老服務管理系統的設計與實現(LW+源碼+講解)

專注于大學生項目實戰開發,講解,畢業答疑輔導,歡迎高校老師/同行前輩交流合作?。 技術范圍:SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬蟲、數據可視化、安卓app、大數據、物聯網、機器學習等設計與開發。 主要內容:…

數字孿生技術如何為制造業開辟新天地?

1. 數字孿生在制造業的崛起背景 1.1 數字孿生的概念演進 “數字孿生”(Digital Twin)一詞最早由美國密歇根大學Michael Grieves博士在2002年提出,但當時并未稱之為“數字孿生”,而是以“信息鏡像模型”描述數字世界與物理世界的映射關系。直到2010年前后,美軍、NASA等在…

學一個前端 UI 框架,要學些什么內容?

假如你現在要自學 React/Vue 框架,怎么學? 絕大部分同學可能是這樣學的: 直接去看官方文檔,或者是找一些視頻看一遍,學會這個框架的一些基礎語法,特性功能等等參考一些例子上手編寫 demo,簡單…

asp.net core mvc模塊化開發

razor類庫 新建PluginController using Microsoft.AspNetCore.Mvc;namespace RazorClassLibrary1.Controllers {public class PluginController : Controller{public IActionResult Index(){return View();}} }Views下Plugin下新建Index.cshtml {ViewBag.Title "插件頁…

2024年MathorCup數學建模C題物流網絡分揀中心貨量預測及人員排班解題全過程文檔加程序

2024年第十四屆MathorCup高校數學建模挑戰賽 C題 物流網絡分揀中心貨量預測及人員排班 原題再現: 電商物流網絡在訂單履約中由多個環節組成,圖1是一個簡化的物流網絡示意圖。其中,分揀中心作為網絡的中間環節,需要將包按照不同流…