MySQL 慢查詢探究分析

目錄

背景:

mysql 整體結構:

SQL查詢語句執行過程是怎樣的:

? 知道了mysql的整體架構,那么一條查詢語句是怎么被執行的呢:

什么是索引:?

建立索引越多越好嗎:  

如何發現慢查詢:

如何優化滿查詢:


背景:

  性能測試過程中,數據庫往往是造成性能瓶頸之一,而數據庫瓶頸中sql 語句又是值得探究分析的一環,其中慢查詢是重點優化對象,在MySQL中,慢查詢是指查詢執行時間較長或者消耗

較多資源的查詢語句。具體來說,MySQL中可以通過設置一個閾值來定義慢查詢,通常默認情況下是超過2秒鐘的查詢會被認為是慢查詢,但是這個閾值可以根據具體情況進行調整。

慢查詢的存在可能會對MySQL數據庫的性能產生負面影響,因為它會占用大量的計算資源和I/O資源,導致其他查詢的響應時間變慢。因此,及時發現并優化慢查詢非常重要。

mysql 整體結構:

MySQL是一個典型的客戶端-服務器(Client-Server)架構系統,它主要由以下幾個組件構成:

  1. 客戶端(Client):客戶端是指連接到MySQL服務器的程序或工具,它們可以通過網絡或本地套接字與MySQL服務器通信。MySQL提供了多種客戶端工具,如mysql命令行工具、MySQL Workbench、phpMyAdmin等。

  2. 連接管理器(Connection Manager):連接管理器負責管理客戶端連接和會話。它接收客戶端的連接請求,并根據配置文件中的參數來限制連接數、最大并發數等,確保MySQL服務器的穩定性和安全性。

  3. 查詢解析器(Query Parser):查詢解析器負責解析客戶端提交的SQL查詢語句,并將其轉換成MySQL服務器可理解的內部數據結構。在此過程中,查詢解析器會檢查查詢語句的語法和語義是否正確,以及權限是否足夠執行該查詢。

  4. 優化器(Optimizer):優化器是MySQL查詢執行的關鍵組件,它負責優化查詢執行計劃,以獲得最佳的執行效率。優化器會分析查詢語句,選擇最優的索引、表的訪問順序、連接方式等來執行查詢。MySQL提供了多種優化器,如基于規則的優化器、基于成本的優化器等。

  5. 存儲引擎(Storage Engine):存儲引擎是MySQL數據庫中存儲和管理數據的核心組件。MySQL支持多種存儲引擎,如InnoDB、MyISAM、MEMORY等。每個存儲引擎都有其獨特的特性和適用場景,如InnoDB適合于高并發、事務性操作,MyISAM適合于讀密集型操作等。

  6. 緩存(Cache):緩存是MySQL性能優化的重要手段之一。MySQL提供了多種緩存機制,如查詢緩存、表緩存、緩沖池等。查詢緩存可以緩存查詢結果,以減少重復查詢的開銷;表緩存可以緩存表結構,以加速表的訪問;緩沖池可以緩存磁盤上的數據,以提高數據訪問的速度。

總的來說,MySQL架構是由客戶端、連接管理器、查詢解析器、優化器、存儲引擎和緩存等組件構成的。每個組件都有其獨特的作用和功能,共同協作來實現MySQL數據庫系統的高效穩定運行。

SQL查詢語句執行過程是怎樣的:

? 知道了mysql的整體架構,那么一條查詢語句是怎么被執行的呢:

  你會先連接到這個數據庫上,這時候接待你的就是連接器,連接建立完成后,執行邏輯就會來到查詢緩存。如果開啟來了查詢緩存,之前執行過的語句及其結果可能會以 key-value 對的形

式,被直接緩存在內存中。如果命中,value直接返回給客戶端。沒有命中,則繼續。執行完成后,執行結果會被存入查詢緩存中。如果沒有命中查詢緩存,進入分析器,通過詞法分析+語法分

析對 SQL 語句做解析,語法錯誤是從這個環節報出的。優化器是為了提升SQL的執行性能。經過了分析器,MySQL 就知道要做什么了。在開始執行之前,還要先經過優化器的處理。在表里面

有多個索引的時候,決定使用哪個索引;或者在一個語句有多表關聯(join)的時候,決定各個表的連接順序。優化器優化后進入了執行器階段,執行器跟存儲層進行交互,取得執行結果并返

回。

什么是索引:?

  索引是一種用于加速數據庫查詢的數據結構。它可以快速定位到滿足查詢條件的記錄,從而提高查詢效率和性能。簡單來講,索引的出現其實就是為了提高數據查詢的效率,就像書的目錄

一樣,如果你想快速找到其中的某一個知識點,在不借助目錄的情況下,那我估計你可得找一會兒。同樣,對于數據庫的表而言,索引其實就是它的“目錄”。在MySQL中,索引通常是基于B-

Tree(B樹)或哈希表實現的。

  索引主要包括主鍵索引和和非主鍵索引,主鍵索引是建立在表的主鍵列上的索引,而非主鍵索引則是建立在其他列或列組合上的索引。在查詢過程中,主鍵索引和非主鍵索引的查詢方式和效率有所不同。對于主鍵索引,MySQL可以通過B-Tree索引結構快速定位到指定的行記錄,因為主鍵索引唯一,每個值都對應一個行記錄,因此可以直接找到匹配的行記錄。例如,如果需要查詢id為10的學生記錄,可以使用如下的SQL語句:

    SELECT * FROM students WHERE id = 10;

  MySQL會利用主鍵索引快速定位到id為10的行記錄,效率非常高。而對于非主鍵索引,MySQL也可以通過B-Tree索引結構定位到滿足查詢條件的行記錄,但是需要額外的步驟。首先,MySQL會根據非主鍵索引找到滿足查詢條件的行記錄的主鍵值,然后再通過主鍵索引定位到實際的行記錄。例如,如果需要查詢姓名為“Tom”的學生記錄,可以使用如下的SQL語句:

    SELECT * FROM students WHERE name = 'Tom';

MySQL會利用非主鍵索引idx_students_name找到所有姓名為“Tom”的行記錄的主鍵值,然后再根據主鍵索引定位到實際的行記錄。這個過程稱為“回表查詢”,需要額外的IO操作和CPU計

算,因此效率相對較低。如果表中的數據量很大,回表查詢的開銷會更加顯著。

建立索引越多越好嗎:  

  建立索引并不是越多越好,反而可能會對數據庫性能產生負面影響。首先,索引會占用存儲空間,如果過多地建立索引,會導致數據庫占用更多的磁盤空間,對于大型數據庫來說,這可能

會導致磁盤空間不足。其次,索引會影響插入、更新和刪除操作的性能。當進行插入、更新和刪除操作時,MySQL需要更新數據和索引,如果過多地建立索引,就會使這些操作花費更多的時

間,從而降低數據庫的性能。

  最后,索引會影響查詢操作的效率。雖然索引可以加速查詢操作,但是如果過多地建立索引,就會導致MySQL需要在多個索引中選擇最優的索引,這會增加查詢的開銷,并且可能會導致

MySQL選擇不合適的索引,從而降低查詢的效率。因此,在建立索引時,需要根據具體情況進行選擇,避免過多地建立索引。通常情況下,可以考慮在經常使用的列上建立索引,或者在需要優

化查詢的列上建立索引。同時,可以通過監控索引的使用情況,來確定哪些索引需要優化或刪除,以提高數據庫的性能和效率。

如何發現慢查詢:

  1.? 通過設置slow_query_log參數來開啟慢查詢日志,對慢查詢日志進行監控,如果新增慢查詢便立即發送通知。(推薦)

  2.?慢查詢日志分析工具:MySQL提供了一些工具,如mysqldumpslow和mysqlsla,可以根據查詢日志來分析慢查詢,找出執行時間最長的查詢和最頻繁的查詢等信息。

如何優化滿查詢:

情況1 :通過explain你可能會發現,SQL壓根沒走任何索引,而且現在表中的數據量巨大無比。

解決:建合適索引

情況2 :?通過explain查看SQL執行計劃中的key字段。如果發現優化器選擇的Key和你預期的Key不一樣。那顯然是優化器選錯了索引

解決:?最快的解決方案就是:force index ,強制指定索引,或通過增加索引、優化索引、重構查詢語句等方式來提高查詢效率

情況3 :查詢語句復雜或者存在大量子查詢

解決:查詢語句復雜或者存在大量子查詢會影響查詢性能,可以考慮通過優化SQL語句來提高查詢效率。例如,可以使用JOIN語句替換多個子查詢,或者使用WHERE子句限制返回的行數。

分析優化實踐:

假設有一個名為“orders”的表,包含以下列:

  • id: INT,主鍵列
  • customer_id: INT,顧客編號
  • status: ENUM('pending', 'completed', 'cancelled'),訂單狀態
  • order_date: DATETIME,訂單日期
  • amount: DECIMAL(10,2),訂單金額

現在需要查詢所有訂單金額大于1000元的未完成訂單,查詢語句如下:

?SELECT * FROM orders WHERE status = 'pending' AND amount > 1000;

首先,可以通過使用EXPLAIN語句來查看查詢計劃,以了解查詢的執行情況:

EXPLAIN SELECT * FROM orders WHERE status = 'pending' AND amount > 1000;

執行后發現?type列的值是ALL,走的全表掃描;key字段是NULL,沒有使用任何索。接下來,可以在status和amount列上建立索引,建立索引的語句如下:

CREATE INDEX idx_orders_status ON orders (status);
CREATE INDEX idx_orders_amount ON orders (amount);

然后再次執行查詢語句,可以看到查詢效率有了顯著提升,查詢速度大大加快。

優化前的查詢計劃如下所示:

+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| 1 | SIMPLE | orders| NULL | ALL | NULL | NULL | NULL | NULL | 10 | 10.00 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+

優化后的查詢計劃如下所示:

+----+-------------+-------+------------+------+---------------------------+------------------+---------+-------+------+----------+-----------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------------------+------------------+---------+-------+------+----------+-----------------------+
| 1 | SIMPLE | orders| NULL | ref | idx_orders_status,idx_orders_amount | idx_orders_status | 2 | const | 5 | 50.00 | Using index condition |
+----+-------------+-------+------------+------+---------------------------+------------------+---------+-------+------+----------+-----------------------+

可以看到,優化后的查詢計劃使用了idx_orders_status索引,查詢效率大大提高。

因此,通過在status和amount列上建立索引的方式,可以提高查詢效率,降低數據庫的負載和響應時間。但需要注意的是,索引的建立需要根據具體情況進行選擇和應用,過多的索引會影響插

入、更新和刪除操作的性能,因此需要謹慎考慮索引的建立數量和方式。


?以下是我收集到的比較好的學習教程資源,雖然不是什么很值錢的東西,如果你剛好需要,可以評論區,留言【777】直接拿走就好了

各位想獲取資料的朋友請點贊 + 評論 + 收藏,三連!

三連之后我會在評論區挨個私信發給你們~

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

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

相關文章

樹結構--介紹--二叉樹遍歷的遞歸實現

目錄 樹 樹的學術名詞 樹的種類 二叉樹的遍歷 算法實現 遍歷命名 二叉樹的中序遍歷 二叉樹的后序遍歷 二叉樹的后序遍歷迭代算法 二叉樹的前序遍歷 二叉樹的前序遍歷迭代算法 樹 樹是一種非線性的數據結構,它是由n(n≥0)個有限節點組成一個具有層次關系…

Docker安裝 elasticsearch-head

目錄 前言安裝elasticsearch-head步驟1:準備1. 安裝docker2. 搜索可以使用的鏡像。3. 也可從docker hub上搜索鏡像。4. 選擇合適的redis鏡像。 步驟2:拉取elasticsearch-head鏡像拉取鏡像查看已拉取的鏡像 步驟3:創建容器創建容器方式1&#…

SpringBoot復習:(28)【前后端不分離】自定義View

一、自定義View package cn.edu.tju.view;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.stereotype.Comp…

C# --- Case Study

C# --- Case Study C# — Mongo數據庫事務的應用 C# — 如何解析Json文件并注入MongoDB C# — MongoDB如何安全的替換Collection

百度翻譯API整合SpringBoot

案例背景,按照官方給的Demo,實在是太啰嗦了, 大致步驟 封裝數據>簽名>發送請求, 仔細一看劈里啪啦一大堆,最后還要手動關流關連接,難道整合到SpringBoot項目里面我還得為內存管理考慮 所以就有了如下需求 使用 RestTemplate的對象進行發送請求數據,RestTemplate由s…

Redis緩存刪除略和內存淘汰策略及LRU

1、Redis內存若在配置文件中未設置,內存會無限制增長,直到超出物理內存,拋出out of memory內存耗盡異常 解決方法,調整maxmemory參數,一般設置為物理內存的3/4,并且添加緩存刪除策略 2、Redis對于設置了過…

項目經理的會議之道:全參與還是精選參與?

引言 在項目管理中,會議是一個常見的工具,用于溝通信息、解決問題、做出決策等。然而,項目經理是否需要參加所有的會議呢?這是一個值得深思的問題。作為項目經理,我們需要權衡會議的重要性和我們的時間管理。我們不能…

【第一階段】kotlin的函數

函數頭 fun main() {getMethod("zhangsan",22) }//kotlin語言默認是public,kotlin更規范,先有輸入( getMethod(name:String,age:Int))再有輸出(Int[返回值]) private fun getMethod(name:String,age:Int): Int{println("我叫…

Elasticsearch集群shard過多后導致的性能問題分析

1.問題現象 上午上班以后發現ES日志集群狀態不正確,集群頻繁地重新發起選主操作。對外不能正常提供數據查詢服務,相關日志數據入庫也產生較大延時 2.問題原因 相關日志 查看ES集群日志如下: 00:00:51開始集群各個節點與當時的master節點…

Playwright快速上手-1

前言 隨著近年來對UI自動化測試的要求越來越高,,功能強大的測試框架也不斷的涌現。本系列主講的Playwright作為一款新興的端到端測試框架,憑借其獨特優勢,正在逐漸成為測試工程師的熱門選擇。 本系列文章將著重通過示例講解 Playwright python開發環境的搭建 …

Linux Day07

一、僵死進程 1.1僵死進程產生的原因 子進程先于父進程結束, 而父進程沒有獲取子進程退出碼,釋放子進程占用的資源,此時子進程將成為一個僵死進程。 在第一個框這里時父進程子進程都沒有結束,顯示其pid 父進程是2349,子進程是235…

【Nginx】Nginx網站服務

國外主流還是使用apache;國內現在主流是nginx(并發能力強,相對穩定) nginx:高性能、輕量級的web服務軟件 特點: 1.穩定性高(沒apache穩); 2.系統資源消耗比較低&#xf…

Failed to set locale, defaulting to C.UTF-8 或者中文系統語言轉英文系統語言

CentOS 8中執行命令,出現報錯:Failed to set locale, defaulting to C.UTF-8報錯原因: 1、沒有安裝相應的語言包。2、沒有設置正確的語言環境。 解決方法1:安裝語言包 設置語言環境需使用命令 localelocale -a 命令,查…

代碼隨想錄day02

977.有序數組的平方 ● 力扣題目鏈接 ● 給你一個按 非遞減順序 排序的整數數組 nums,返回 每個數字的平方 組成的新數組,要求也按 非遞減順序 排序。 思路 ● 暴力排序,時間復雜度O(n nlogn) ● 使用雙指針,時間復雜度O(n) …

Vue中使用v-bind:class動態綁定多個類名

Vue.js是一個流行的前端框架,它可以幫助開發者構建動態交互的UI界面。在Vue.js開發中,經常需要動態綁定HTML元素的class(類名)屬性,以改變元素的外觀和行為。本文將介紹采用v-bind:class指令在Vue中如何動態綁定多個類…

【大數據】-- 本地部署 Flink kubernetes operator

目錄 1.說明 1.1 版本 1.2 kubernetes 環境 1.3 參考 2.安裝步驟 2.1 安裝本地 kubernetes 環境

判斷鏈表有環的證明

目錄 1.問題 2.證明 3.代碼實現 1.問題 給你一個鏈表的頭節點 head ,判斷鏈表中是否有環。 如果鏈表中有某個節點,可以通過連續跟蹤 next 指針再次到達,則鏈表中存在環。 為了表示給定鏈表中的環,評測系統內部使用…

TansUNet代碼理解

首先通過論文中所給的圖片了解網絡的整體架構: vit_seg_modeling部分 模塊引入和定義相關量: # codingutf-8 # __future__ 在老版本的Python代碼中兼顧新特性的一種方法 from __future__ import absolute_import from __future__ import division fr…

新基建助推數字經濟,CosmosAI率先布局AI超算租賃新紀元

倫敦, 8月14日 - 在英國倫敦隆重的Raffles OWO舉辦的歐盟數字超算新時代戰略合作簽約儀式,CosmosAI、Infinite Money Fund與Internet Research Lab三方強強聯手,達成了歷史性的合作協議,共同邁向超算租賃新紀元。 ? 這次跨界的合作昭示了全球…

Session基礎

文章目錄 什么是Sessionsession與cookie的區別和聯系Session的存Session的取 什么是Session 服務器為每個用戶瀏覽器創建一個會話對象(session對象),一個瀏覽器只能產生一個session當新建一個窗口訪問服務器時,還是原來的那個ses…