Mysql為什么有時候會選錯索引

案例

正常情況

有一個表t ( id, a , b ),id是主鍵索引,a是Normal索引。

正常情況下,針對a進行查詢,可以走索引a
在這里插入圖片描述
并且查詢的數量和預估掃描行數是差不多的,都是10001行
在這里插入圖片描述

奇怪的現象

隨著時間的變化,后面可能就會發生下面的情況
在這里插入圖片描述
根據explain計劃,我們發現數據還是那么多,但是不走a索引了,并且優化器知道有a索引,但是最終還是走了全表掃描。

優化器的邏輯

先了解一下優化器
選擇索引是優化器的工作,而優化器選擇索引的目的,是找到一個最優的執行方案,并用最小的代價去執行語句。在數據庫里面,掃描行數是影響執行代價的因素之一。掃描的行數越少,意味著訪問磁盤數據的次數越少,消耗的 CPU 資源越少(掃描行數并不是唯一的判斷標準,優化器還會結合是否使用臨時表、是否排序等因素進行綜合判斷)

下面只討論掃描行數帶來的影響
那么優化器是怎么去估算需要掃描多少行?
在這里插入圖片描述
我們可以通過命令看到有一個Cardinality(基數),選擇索引需要掃描的行數就是通過它來判斷的,它代表一個索引上不同的值的個數,值越大說明區分度越高,那么越有可能走這個索引

優化器的選擇一定對么?

上面看到針對下面這個sql,優化器覺得全表掃描更合適,但實際上真的是速度最快的么?

select * from t where a between 10000 and 20000;

我們實際執行一下:
在這里插入圖片描述
不接受優化器的建議,強行走a索引執行一下:
在這里插入圖片描述
重點看3個指標:Query_time(執行耗時)、Rows_sent(返回行數)、Rows_examined(掃描/行數)
我們發現強行走索引a其實更快,實際掃描行數也少。那么為什么優化器不走索引a呢?

我們再執行一個命令(更新表的統計信息):

ANALYZE TABLE t;

然后我們再看一下執行計劃:

explain select * from t where a between 10000 and 20000;

在這里插入圖片描述
發現優化器竟然又選擇了索引a,說明是因為統計信息不準確,沒有及時更新導致優化器進行了錯誤的選擇。
接著實際執行一下:

select * from t where a between 10000 and 20000;

在這里插入圖片描述
我們發現實際的掃描行數和預估的掃描行數對上了,并且也確實走了索引a,耗時也降下來了
最后我們再看一下索引的統計信息
在這里插入圖片描述
統計信息確實和上面不一樣了,更新了。但是這里有個問題是:雖然統計信息不一樣了(能確保確實更新索引統計信息的sql起作用了)但統計信息和一開始也差不多,為什么Cardinality值差不多的情況下,優化器做出了不一樣的選擇?
因為實際上表數據經歷了大量的刪除、新增操作,Cardinality不會更新一些還未提交的事務數據,所以看似基數差不多,實際上基數不一樣優化器對主鍵的判斷是基于實際表行數來判斷的,所以主鍵的判斷是準的,不準的是其他索引的統計信息。

總結

本文討論了Mysql(InnoDB)在索引統計信息不準確或更新不及時的情況下,優化器基于統計信息進行粗估的執行計劃,可能會選錯索引。
我們一般應對的方法如下:

  1. 更新索引統計信息
  2. 修改SQL語句強制走固定索引
  3. 新增索引(比如上面新增一個索引a,b)
  4. 刪除索引(假設優化器選擇了索引b,確保該索引沒有其他作用的前提下,那么刪掉索引b,可能就會走索引a了)

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

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

相關文章

[250414] ArcoLinux 項目宣布逐步結束

目錄 ArcoLinux 項目宣布逐步結束 ArcoLinux 項目宣布逐步結束 備受歡迎的 Arch Linux 發行版 ArcoLinux 近日宣布,其項目將逐步結束。ArcoLinux 以其作為 Linux 教育平臺和提供多種安裝選項(從完整桌面環境到最小化基礎安裝)而聞名。 核心…

opencv人臉性別年齡檢測

一、引言 在計算機視覺領域,人臉分析是一個熱門且應用廣泛的研究方向。其中,人臉性別年齡檢測能夠自動識別圖像或視頻流中人臉的性別和年齡信息,具有諸多實際應用場景,如市場調研、安防監控、用戶個性化體驗等。OpenCV 作為一個強…

【NLP】 22. NLP 現代教程:Transformer的訓練與應用全景解讀

🧠 NLP 現代教程:Transformer的訓練與應用全景解讀 一、Transformer的使用方式(Training and Use) 如何使用Transformer模型? Transformer 模型最初的使用方式有兩種主要方向: 類似 RNN 編碼-解碼器的架…

Spring Boot 集成 RocketMQ 全流程指南:從依賴引入到消息收發

前言 在分布式系統中,消息中間件是解耦服務、實現異步通信的核心組件。RocketMQ 作為阿里巴巴開源的高性能分布式消息中間件,憑借其高吞吐、低延遲、高可靠等特性,成為企業級應用的首選。而 Spring Boot 通過其“約定優于配置”的設計理念&a…

HTTPS實現安全的關鍵方法及技術細節

HTTPS(HyperText Transfer Protocol Secure)通過多種技術手段實現數據傳輸的安全性,其核心機制基于SSL/TLS協議,并結合數字證書、加密算法等技術。 SSL:Secure Sockets Layer,安全套接字層 TLS:…

Java【多線程】(8)CAS與JUC組件

目錄 1.前言 2.正文 2.1CAS概念 2.2CAS兩種用途 2.2.1實現原子類 2.2.2實現自旋鎖 2.3缺陷:ABA問題 2.4JUC組件 2.4.1Callable接口 2.4.2ReentrantLock(與synchronized對比) 2.4.3Semaphore信號量 2.4.4CountDownLatch 3.小結 1…

【Docker】離線安裝Docker

背景 離線安裝Docker的必要性,第一,在目前數據安全升級的情況下,很多外網已經基本不好訪問了。第二,如果公司有對外部署的需求,那么難免會存在對方只有內網的情況,那么我們就要做到學會離線安裝。 下載安…

MecAgent Copilot:機械設計師的AI助手,開啟“氛圍建模”新時代

MecAgent Copilot作為機械設計師的AI助手,正通過多項核心技術推動機械設計進入“氛圍建模”新時代。以下從功能特性、技術支撐和應用場景三方面解析其創新價值: 一、核心功能特性 ??智能草圖生成與參數化建模?? 支持自然語言輸入生成設計草圖和3D模型,如輸入“剖面透視…

MCU屏和RGB屏

一、MCU屏 MCU屏?:全稱為單片機控制屏(Microcontroller Unit Screen),在顯示屏背后集成了單片機控制器,因此,MCU屏里面有專用的驅動芯片。驅動芯片如:ILI9488、ILI9341、SSD1963等。驅動芯片里…

7.5 使用MobileNet v3進行圖像的區分

MobileNet v3是Google在2019年提出的輕量級卷積神經網絡結構,旨在提高在移動設備上的速度和準確性,廣泛的用于輕量級網絡。 MobileNet v3-Small的網絡結構如下,它的輸入是224x224的3通道彩色圖片。 使用過程如下: 1.創建模型、修改最終分類數量 #1.創建mobilenet_v3_small…

構建面向大模型訓練與部署的一體化架構:從文檔解析到智能調度

作者:汪玉珠|算法架構師 標簽:大模型訓練、數據集構建、GRPO、自監督聚類、指令調度系統、Qwen、LLaMA3 🧭 背景與挑戰 隨著 Qwen、LLaMA3 等開源大模型不斷進化,行業逐漸從“能跑通”邁向“如何高效訓練與部署”的階…

PostgreSQL技術大講堂 - 第86講:數據安全之--data_checksums天使與魔鬼

PostgreSQL技術大講堂 - 第86講,主題:數據安全之--data_checksums天使與魔鬼 1、data_checksums特性 2、避開DML規則,嫁接非法數據并合法化 3、避開約束規則,嫁接非法數據到表中 4、避開數據檢查,讀取壞塊中的數據…

【機器學習】機器學習筆記

1 機器學習定義 計算機程序從經驗E中學習,解決某一任務T,進行某一性能P,通過P測定在T上的表現因經驗E而提高。 eg:跳棋程序 E: 程序自身下的上萬盤棋局 T: 下跳棋 P: 與新對手下跳棋時贏的概率…

Ubuntu20.04 設置開機自啟

參考: Ubuntu20.04 設置開機自啟_ubuntu進bos系統-CSDN博客

數據庫中存儲過程的流程語句講解

一、流程語句講解 二、總結 一、流程語句講解 1.1 if語句講解 語法: IF condition THENstatements; ELSEIF condition THENstatements; ELSEstatements; END IF; 題目示例: # 判斷成績等級 # 輸入學生的編號,取出學生的第一門課,然后判斷…

kubernetes》》k8s》》ConfigMap 、Secret

configmap官網 ConfigMap是一種 API 對象,使用時, Pods 可以將其用作環境變量、命令行參數或者存儲卷中的配置文件。ConfigMap將配置和Pod解耦,更易于配置文件的更改和管理。ConfigMap 并不提供保密或者加密功能。 如果你想存儲的數據是機密的…

git在IDEA中使用技巧

git在IDEA中使用技巧 merge和rebase 參考:IDEA小技巧-Git的使用 git回滾、強推、代碼找回 參考:https://www.bilibili.com/video/BV1Wa411a7Ek?spm_id_from333.788.videopod.sections&vd_source2f73252e51731cad48853e9c70337d8e cherry pick …

Spring 事務失效的原因及解決方案全解析,來復習了

Spring 事務失效是指在使用 Spring 聲明式事務管理時,預期的事務行為(如事務的開啟、提交、回滾等)未按預期執行,導致數據操作未滿足 ACID 特性(原子性、一致性、隔離性、持久性),從而引發數據不…

「出海匠」借助CloudPilot AI實現AWS降本60%,支撐AI電商高速增長

🔎公司簡介 「出海匠」(chuhaijiang.com)是「數繪星云」公司打造的社交內容電商服務平臺,專注于為跨境生態參與者提供數據支持與智能化工作流。平臺基于大數據與 AI 技術,幫助商家精準分析市場趨勢、優化運營策略&…

python每日一練

題目一 輸入10個整數,輸出其中不同的數,即如果一個數出現了多次,只輸出一次(要求按照每一個不同的數第一次出現的順序輸出)。 解題 錯誤題解 a list(map(int,input().split())) b [] b.append(a[i]) for i in range(2,11):if a[i] not in b:b.append(a[i]) print(b)但是會…