數據庫優化

一、慢 SQL 排查全流程

1. 開啟慢查詢日志:精準定位問題 SQL

慢查詢日志是定位性能問題的首要工具,通過記錄執行超時或未使用索引的 SQL,為優化提供依據。

配置步驟:

① 臨時啟用(生效至服務重啟)

sql

-- 開啟慢查詢日志
SET GLOBAL slow_query_log = ON;
-- 設置超時閾值(單位:秒,默認10秒,建議設為1秒)
SET GLOBAL long_query_time = 1;
-- 記錄未使用索引的查詢(即使執行時間未超時)
SET GLOBAL log_queries_not_using_indexes = ON;

② 永久生效(修改配置文件)
編輯 MySQL 配置文件(my.cnf/my.ini):

ini

[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log  # 日志存儲路徑
long_query_time = 1
log_queries_not_using_indexes = 1

③ 查看日志位置

sql

SHOW VARIABLES LIKE 'slow_query_log_file';
分析工具:
  • mysqldumpslow(內置工具,命令行分析):

    bash

    # 按執行時間排序,取最慢的10條SQL
    mysqldumpslow -s t -t 10 /var/log/mysql/slow.log  
    # 按訪問次數排序,取最頻繁的10條SQL
    mysqldumpslow -s c -t 10 /var/log/mysql/slow.log  
    
  • pt-query-digest(Percona Toolkit,功能更強):

    bash

    pt-query-digest /var/log/mysql/slow.log > slow_analysis.txt
    

2. 解析 EXPLAIN 執行計劃:洞察查詢邏輯

EXPLAIN通過可視化執行步驟,揭示 SQL 是否有效利用索引、掃描行數等關鍵信息。

核心字段解讀:
字段含義與優化重點
type連接類型(效率從高到低):system?>?const?>?eq_ref?>?ref?>?range?>?index?>?ALL
** 警惕ALL(全表掃描),必須通過索引優化。
key實際使用的索引,若為NULL表示未用索引,需檢查WHERE/JOIN條件是否命中索引。
rows估算掃描行數,數值越小越好,全表掃描時可能等于表數據量。
Extra-?Using filesort:需額外排序(優化:為ORDER BY字段加索引)
-?Using temporary:使用臨時表(優化:簡化GROUP BY/DISTINCT邏輯)
-?Using index:覆蓋索引(理想狀態,無需回表)。
示例分析:

sql

EXPLAIN SELECT u.name, o.order_date 
FROM users u 
JOIN orders o ON u.id = o.user_id 
WHERE u.age > 30 AND o.status = 'paid';

idtypekeyrowsExtra
1rangeidx_age1000Using where
1refidx_user_id5Using where

結論

  • users表通過idx_age索引掃描 1000 行(范圍查詢),性能可接受;
  • orders表通過user_id索引關聯,但status字段未用索引,建議創建復合索引(user_id, status)

二、索引失效的六大典型場景

1. 全值匹配時順序錯誤(復合索引)

場景:復合索引(a, b, c),查詢WHERE b=1WHERE a=1 AND c=1
原因:索引需按順序匹配,中間字段跳過則后續失效。
修復:查詢條件包含索引最左前綴(如a=1 AND b=1)。

2. 范圍查詢后字段未使用索引

場景WHERE a > 10 AND b=20,若a是范圍查詢(>,?<,?BETWEEN),b字段的索引失效。
原因:MySQL 僅對第一個范圍字段使用索引,后續字段無法利用。
修復:對高頻查詢字段調整順序,如復合索引(b, a)

3. 數據類型隱式轉換

場景:字段user_idINT,查詢WHERE user_id = '123a'(字符串轉數字失敗)或WHERE phone='13812345678'但字段定義為INT
原因:類型不匹配導致索引失效,轉為全表掃描。
修復:確保查詢條件與字段類型一致(避免字符串加引號查詢數字字段)。

4. 索引字段使用函數或表達式

場景WHERE YEAR(create_time) = 2023?或?WHERE id + 1 = 5
原因:對索引字段使用函數 / 計算,MySQL 無法命中索引。
修復:改寫為WHERE create_time >= '2023-01-01' AND create_time < '2024-01-01'

5. OR 條件連接非索引字段

場景WHERE id=1 OR name='Alice',若name無索引,則整個條件退化為全表掃描。
原因OR兩側字段必須都有索引才會生效,否則放棄索引。
修復:為name添加索引,或改用UNION拆分查詢。

6. 模糊查詢以通配符開頭

場景WHERE name LIKE '%abc'?或?WHERE name LIKE '%abc%'
原因:左模糊(%開頭)無法利用索引,僅右模糊(abc%)可命中。
修復:避免左模糊查詢,或使用全文索引(Full-Text Index)。

三、索引高級特性:下推與覆蓋

1. 索引下推(Index Condition Pushdown, ICP)

原理:MySQL 5.6 + 引入的優化,在索引遍歷過程中,直接過濾掉不滿足WHERE條件的記錄,減少回表次數。
示例:表users有索引(name, age),查詢WHERE name LIKE 'A%' AND age=20

  • 無 ICP:通過name索引找到所有以 'A' 開頭的記錄,回表后再過濾age=20
  • 有 ICP:在索引層直接判斷age=20,僅對符合條件的記錄回表,減少 I/O。
    開啟方式:默認啟用,可通過SHOW VARIABLES LIKE 'optimizer_switch'查看index_condition_pushdown狀態。

2. 索引覆蓋(Covering Index)

定義:查詢所需的所有字段都包含在索引中,無需回表查詢原數據,是索引優化的終極目標。
示例:表orders有索引(user_id, status, order_time),查詢SELECT status, order_time FROM orders WHERE user_id=1

  • 覆蓋索引:直接通過索引獲取數據,效率極高(Extra顯示Using index)。
  • 非覆蓋索引:若索引缺少order_time,需回表查詢完整行數據。
    設計原則:為高頻查詢語句創建包含所有 SELECT 字段的復合索引,避免SELECT *

四、最佳實踐總結

  1. 慢 SQL 排查閉環
    開啟慢日志 → 分析日志定位問題 SQL → 用EXPLAIN剖析執行計劃 → 針對性優化索引或查詢語句。
  2. 索引設計三原則
    • 最左前綴匹配:復合索引按查詢條件順序創建;
    • 覆蓋索引優先:減少回表,提升查詢速度;
    • 避免過度索引:索引過多會影響寫入性能(插入 / 更新 / 刪除)。
  3. 工具鏈推薦
    • 日志分析:pt-query-digest(全面統計)、mysqldumpslow(快速預覽);
    • 可視化:MySQL Workbench(圖形化執行計劃)、Navicat(索引管理)。

通過系統化排查與索引優化,可顯著提升 MySQL 查詢性能,避免因慢 SQL 導致的系統瓶頸。

編輯

分享

在排查慢 SQL 時,如何確定慢查詢的閾值?

如何選擇合適的索引來優化查詢性能?

分享一些排查和優化 MySQL 慢 SQL 的實際案例

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

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

相關文章

GO語言-導入自定義包

文章目錄 1. 項目目錄結構2. 創建自定義包3. 初始化模塊4. 導入自定義包5. 相對路徑導入 在Go語言中導入自定義包需要遵循一定的目錄結構和導入規則。以下是詳細指南&#xff08;包含兩種方式&#xff09;&#xff1a; 1. 項目目錄結構 方法1&#xff1a;適用于Go 1.11 &#…

記錄算法筆記(2025.5.11) 二叉樹的中序遍歷

給定一個二叉樹的根節點 root &#xff0c;返回 它的 中序 遍歷 。 示例 1&#xff1a; 輸入&#xff1a;root [1,null,2,3] 輸出&#xff1a;[1,3,2] 示例 2&#xff1a; 輸入&#xff1a;root [] 輸出&#xff1a;[] 示例 3&#xff1a; 輸入&#xff1a;root [1] …

【iptables防火墻】 -- DDos防御

最近有客戶要定制路由器的默認防火墻等級&#xff0c;然后涉及到了DDos規則&#xff0c;對比客戶提供的規則發現我們現有的規則存在明顯的錯誤&#xff0c;在此記錄一下如何使用iptables防護DDoS攻擊 直接貼一下規則 #開啟TCP SYN Cookies 機制 sysctl -w net.ipv4.tcp_synco…

[Java][Leetcode simple]26. 刪除有序數組中的重復項

思路 第一個元素不動從第二個元素開始&#xff1a;只要跟上一個元素不一樣就放入數組中 public int removeDuplicates(int[] nums) {int cnt1;for(int i 1; i < nums.length; i) {if(nums[i] ! nums[i-1]) {nums[cnt] nums[i];}}return cnt;}

微服務!!

1.Nacos注冊中心 2.服務注冊 3.服務發現 4.負載均衡 5.OpenFeign 6.OpenFeign連接池 啟動程序 7.路由 8.微服務保護 1.雪崩問題 2.解決方案 1.請求限流 2.線程隔離 3.服務熔斷 3.Sentinel 1.鏈路 2.請求限流 3.線程隔離 4.Fallback 5.服務熔斷 4.分布式事務 1.Seata 2.部…

代碼隨想錄算法訓練營 Day44 動態規劃 ⅩⅠ 子序列問題

動態規劃 題目 1143. 最長公共子序列 - 力扣&#xff08;LeetCode&#xff09; 公共子序列&#xff0c;類似于最長重復子數組&#xff0c;但是不要求連續 (子序列) 1. 定義 dp&#xff0c;dp[i][j] 表示以 i-1 與 j-1 結尾的最長公共子序列的長度 2. 定義遞推公式 如果字符相…

聊一聊接口測試依賴第三方服務變更時如何處理?

目錄 一、依賴隔離與模擬 二、契約測試 三、版本控制與兼容性 四、變更監控與告警 五、容錯設計 六、自動化測試維護 七、協作機制與文檔自動化 第三方API突然改了參數或者返回結構&#xff0c;導致我們的測試用例失敗&#xff0c;這時候該怎么辦呢&#xff1f;首先想到…

Python程序,輸入IP,掃描該IP哪些端口對外是開放的,輸出端口列表

#!/usr/bin/env python # -*- coding: utf-8 -*-""" IP端口掃描程序 輸入IP地址&#xff0c;掃描該IP哪些端口對外是開放的&#xff0c;輸出端口列表 """import socket import sys import concurrent.futures import ipaddress from tabulate im…

Python----神經網絡(《Inverted Residuals and Linear Bottlenecks》論文概括和MobileNetV2網絡)

一、論文 MobileNetV2 論文提出了一種新的移動架構&#xff0c;該架構提高了移動模型在多個任務和基準測試中的性能&#xff0c;以及在各種不同模型大小范圍內的性能. 該架構基于倒殘差結構&#xff0c;其中 shortcut 連接在 thin bottleneck 層之間. 中間的 expansion 層使用輕…

Maven私服搭建與登錄全攻略

目錄 1.背景2.簡介3.安裝4.啟動總結參考文獻 1.背景 回顧下maven的構建流程&#xff0c;如果沒有私服&#xff0c;我們所需的所有jar包都需要通過maven的中央倉庫或者第三方的maven倉庫下載到本地&#xff0c;當一個公司或者一個團隊所有人都重復的從maven倉庫下載jar包&#…

EF Core 數據庫遷移命令參考

在使用 Entity Framework Core 時&#xff0c;若你希望通過 Package Manager Console (PMC) 執行遷移相關命令&#xff0c;以下是常用的 EF Core 遷移命令&#xff1a; PMC 方式 ? 常用 EF Core PMC 命令&#xff08;適用于遷移&#xff09; 操作PMC 命令添加遷移Add-Migra…

商業 |阿里云又丟出了核彈

行業翹首以盼的DeepSeek-R2沒等到&#xff0c;阿里云卻先一步丟出了核彈。 4月29日凌晨&#xff0c;阿里云正式上線了Qwen3系列模型“全家桶”&#xff0c;包含2個MoE模型、6個稠密模型。 八個模型&#xff0c;小到0.6B大到235B&#xff0c;既能在手機使用&#xff0c;也有旗…

《Python星球日記》 第66天:序列建模與語言模型

名人說:路漫漫其修遠兮,吾將上下而求索。—— 屈原《離騷》 創作者:Code_流蘇(CSDN)(一個喜歡古詩詞和編程的Coder??) 目錄 一、傳統語言模型1. n-gram 模型基礎2. n-gram 模型的局限性二、RNN 在語言建模中的應用1. 語言模型的基本原理2. RNN 構建語言模型的優勢3. 實…

20250510解決NanoPi NEO core開發板在Ubuntu core22.04.3系統下適配移遠的4G模塊EC200A-CN的問題

1、h3-eflasher-friendlycore-jammy-4.14-armhf-20250402.img.gz 在WIN10下使用7-ZIP解壓縮/ubuntu20.04下使用tar 2、Win32DiskImager.exe 寫如32GB的TF卡。【以管理員身份運行】 3、TF卡如果已經做過會有3個磁盤分區&#xff0c;可以使用SD Card Formatter/SDCardFormatterv5…

C# 的異步任務中, 如何暫停, 繼續,停止任務

namespace taskTest {using System;using System.Threading;using System.Threading.Tasks;public class MyService{private Task? workTask;private readonly SemaphoreSlim semaphore new SemaphoreSlim(0, 1); // 初始為 0&#xff0c;Start() 啟動時手動放行private read…

關于nextjs中next-sitemap插件生成文件樣式丟失問題及自定義樣式處理

現象沒有默認樣式 修改后 代碼配置如下 next-sitemap.config.js如下 // const { routing } require(./src/i18n/routing) ;const { flatten } require(lodash) const fs require(fs); const path require(path);// 改為硬編碼locales值&#xff0c;與routing.ts保持一…

圖片的require問題

問題 <template><!--第一種方式--><img :src"require(/assets/${imageName})" style"width:100px;" /><!--第二種方式--><img :src"require(imageUrl)" style"width:100px;" /> </template><…

【官方題解】StarryCoding 入門教育賽 2 | acm | 藍橋杯 | 新手入門

比賽傳送門&#xff1a; 本場比賽開始時題面存在一些問題&#xff0c;私密馬賽&#xff01; A.池化【入門教育賽】 根據題目所給公式計算即可。 #include "bits/stdc.h"signed main() {int t; std::cin >> t;while (t --) {int l, k, s, p; std::cin >&…

課題推薦——低成本地磁導航入門,附公式推導和MATLAB例程運行演示

地磁導航利用地球磁場的自然特性&#xff0c;通過感知磁場變化&#xff0c;幫助機器人或無人設備實現定位和導航。相比于 GPS、激光雷達等導航方法&#xff0c;地磁導航具有以下優勢&#xff1a; 低成本&#xff1a;使用地磁傳感器&#xff08;如電子羅盤&#xff09;&#xff…

【人工智能】自然語言編程革命:騰訊云CodeBuddy實戰5步搭建客戶管理系統,效率飆升90%

CodeBuddy 導讀一、產品介紹1.1 **什么是騰訊云代碼助手&#xff1f;**1.2 插件安裝1.2.1 IDE版本要求1.2.2 注意事項1.2.4 插件安裝1.2.4.1 環境安裝1.2.4.2 安裝騰訊云AI代碼助手** 1.2.5 功能介紹1.2.5.1 Craft&#xff08;智能代碼生成&#xff09;1.2.5.2 Chat&#xff08…