索引的選擇與Change Buffer

1. 索引選擇與Change Buffer

問題引出:普通索引 vs 唯一索引 ——如何選擇?

在實際業務中,如果一個字段的值天然具有唯一性(如身份證號),并且業務代碼已確保無重復寫入,那就存在兩種選擇:

  • 創建唯一索引
  • 創建普通索引

雖然邏輯上兩者都可以正確工作,但從 性能角度看,應該如何選擇呢?

1.1. 查詢場景下的性能差異

查詢語句示例:

SELECT name FROM CUser WHERE id_card = 'xxxxxxxyyyyyyzzzzz';

查詢過程分析:

  • InnoDB 使用 B+ 樹索引,查找過程是按層遍歷到葉子節點。
  • 普通索引

找到首個滿足條件的記錄后,還會繼續查找,直到條件不再滿足。

  • 唯一索引

找到首個滿足條件的記錄后立即停止。

性能差距分析:

  • InnoDB 是按數據頁(默認16KB)為單位讀取的。
  • 也就是說,命中一條記錄時,整個數據頁已在內存中
  • 普通索引多做一次判斷和指針移動,性能開銷極小,可以忽略不計。

結論:查詢性能差異微乎其微

1.2. 更新場景下的性能差異 (關注 Change Buffer )

Change Buffer 的概念:

  • 又稱 變更緩沖區,用于緩存針對尚未加載入內存的數據頁的 DML 操作。
  • 目的是延遲磁盤讀寫,提升寫性能。
  • 持久化存儲,內存+磁盤雙存儲。

Merge 操作:

  • 當數據頁被訪問或系統后臺線程定期觸發時,change buffer 會被合并(merge)到實際數據頁中。

兩種索引對比:

特性

唯一索引

普通索引

查詢性能差距

幾乎無

幾乎無

是否能使用 Change Buffer

? 不能使用

? 可以使用

寫入磁盤前是否需加載數據頁

? 是

? 否

寫多讀少場景優化空間

?? 受限

? 提升明顯

建議使用場景

嚴格校驗唯一性

默認首選

  • 唯一索引需驗證是否存在重復值,必須讀入數據頁判斷唯一性,無法延遲IO。
  • 而普通索引可以直接緩存寫操作,延遲數據頁加載。

1.3. Change Buffer 的影響和適用場景

Change Buffer 的實際影響分析

1. 情況一:目標頁在內存中

  • 唯一索引:讀內存判斷唯一性后插入,結束。
  • 普通索引:直接插入,結束。
  • ? 性能差異極小

2. 情況二:目標頁不在內存中

  • 唯一索引:

需要將目標頁從磁盤加載入內存進行唯一性判斷 → 高成本的隨機 IO

  • 普通索引:

操作直接寫入 Change Buffer,延遲磁盤讀寫 → 性能提升明顯

這是唯一索引與普通索引的性能關鍵差異點!

Change Buffer 的適用場景

適用場景 :

  • 寫多讀少 的系統
    例如:日志系統、賬單系統等
    頁面寫完之后很少會被立即查詢,Change Buffer 能發揮顯著優勢。

不適用場景 :

  • 寫后立刻讀 的業務模型

寫操作剛緩存就被查詢命中,觸發 merge,反而增加了維護成本。

實際應用建議

  • 查詢性能差異不大,但更新性能差異明顯
  • 盡量優先選擇普通索引,除非業務邏輯依賴數據庫強一致性校驗。
  • 寫多讀少場景下,配合開啟 Change Buffer(默認開啟),顯著優化性能。
  • 使用機械硬盤時,Change Buffer 的效果更明顯,應適當調大 innodb_change_buffer_max_size 參數(如 50%)
  • 若寫后即讀,可以考慮 關閉 Change Buffer

2. MySQL選錯索引問題分析

2.1. 索引錯選問題

問題背景與現象:

  • 有時 MySQL 執行 SQL 時并沒有選擇最佳索引,導致性能下降。
  • 通過一個具體例子說明了優化器因估算錯誤而選錯索引的情況。

實驗設計:

1. 表結構與索引

CREATE TABLE t (a INT,b INT,c INT,INDEX(a),INDEX(b)
);

2. 數據插入

  • 插入數據:(1,1,1)(100000,100000,100000) 共 10 萬行。

預期查詢語句

SELECT * FROM t WHERE a BETWEEN 10000 AND 20000;

3. 實驗步驟(關鍵觸發邏輯)

  • Session A:開啟事務,未提交;
  • Session B:

刪除所有數據;

重新插入 10 萬行;

執行上面的查詢。

4. 異常現象

  • 查詢變慢,發現 優化器選擇了全表掃描 而不是走 a 的索引。

執行計劃對比與影響分析:

Q1:默認語句

SELECT * FROM t WHERE a BETWEEN 10000 AND 20000;
  • 使用了全表掃描,rows = 104620
  • 掃描耗時約 40ms

Q2:強制使用索引

SELECT * FROM t FORCE INDEX(a) WHERE a BETWEEN 10000 AND 20000;
  • 使用索引 arows = 10001
  • 掃描耗時約 21ms
  • 結論:Q2 明顯更優

2.2. MySQL 優化器選錯索引原因

優化器目標

  • 找出 執行代價最小 的執行計劃;
  • 代價估算核心:行數(row estimate) + 回表成本

行數估算依賴“統計信息”

  • MySQL 使用索引的基數(cardinality) 估算結果行數;
  • 采樣得出,不一定準確;
  • 命令查看基數:
SHOW INDEX FROM t;

統計信息采樣機制

  • 參數 innodb_stats_persistent

ON:采樣頁數 20,觸發更新閾值 10

OFF:采樣頁數 8,觸發更新閾值 16

  • 采樣帶來的估算誤差:

優化器以為 a between 10000 and 20000 會返回約 37000 行;

實際只有 10001 行,高估了結果量

回表代價高估

  • 索引 a 是二級索引,取出數據后需要回主鍵索引查全行(回表);
  • 優化器認為:

37000 次回表 ≈ 37000 次隨機 IO;

而全表掃描只需約 100 頁順序讀;

所以選擇全表掃描。

2.3. 驗證與解決方案

觀察 EXPLAIN 輸出

EXPLAIN SELECT * FROM t WHERE a BETWEEN 10000 AND 20000;
  • rows ≈ 37116(高估)→ 優化器認為成本更高。

修復手段:更新統計信息

ANALYZE TABLE t;
  • 執行后重新 EXPLAIN,rows 變為 10001;
  • 優化器重新選擇正確索引。

總結與實踐建議

類別

內容

問題核心

優化器因統計信息誤差、高估回表代價,選錯了索引

典型表現

EXPLAIN 中 rows

顯著高估;執行計劃走了全表掃描

核心原因

索引基數估算不準確;二級索引導致回表開銷被放大

解決辦法

使用 ANALYZE TABLE

更新統計信息

實踐建議

當發現慢查詢/rows 異常時,第一步先做統計更新;必要時使用 force index

臨時規避

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

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

相關文章

lua注意事項

感覺是lua的一大坑啊,它還不如函數內部就局部變量呢 注意函數等內部,全部給加上local得了

【多線程初階】死鎖的產生 如何避免死鎖

文章目錄 關于死鎖一.死鎖的三種情況1.一個線程,一把鎖,連續多次加鎖2.兩個線程,兩把鎖3.N個線程,M把鎖 --哲學家就餐問題 二.如何避免死鎖死鎖是如何構成的(四個必要條件)打破死鎖 三.死鎖小結 關于死鎖 一.死鎖的三種情況 1.一個線程,一把鎖,連續多次加鎖 -->由synchroni…

【NLP基礎知識系列課程-Tokenizer的前世今生第二課】NLP 中的 Tokenizer 技術發展史

從詞表到子詞:Tokenizer 的“進化樹” 我們常說“語言模型是理解人類語言的工具”,但事實上,模型能不能“理解”,關鍵要看它接收到了什么樣的輸入。而 Tokenizer,就是這一輸入階段的設計者。 在 NLP 的發展歷程中&am…

Rust 學習筆記:循環和迭代器的性能比較

Rust 學習筆記:循環和迭代器的性能比較 Rust 學習筆記:循環和迭代器的性能比較示例 1示例 2總結 Rust 學習筆記:循環和迭代器的性能比較 示例 1 我們運行一個基準測試,將《福爾摩斯探案集》的全部內容加載到一個字符串中&#x…

pod創建和控制

一、引言 ?主題?:pod以及控制器模式中的Deployment作用。?控制器模式:使用一種API對象(如Deployment)管理另一種API對象(如Pod)的方式。 二、容器鏡像與配置文件 ?容器鏡像?:應用開發者…

HTML實戰:愛心圖的實現

設計思路 使用純CSS創建多種風格的愛心 添加平滑的動畫效果 實現交互式愛心生成器 響應式設計適應不同設備 優雅的UI布局和色彩方案 <!DOCTYPE html> <html lang"zh-CN"> <head> <meta charset"UTF-8"> <meta nam…

2022年 中國商務年鑒(excel電子表格版)

2022年 中國商務年鑒&#xff08;excel電子表格版&#xff09;.ziphttps://download.csdn.net/download/2401_84585615/89772883 https://download.csdn.net/download/2401_84585615/89772883 《中國商務年鑒2022》是由商務部國際貿易經濟合作研究院主辦的年度統計資料&#xf…

Redis核心數據結構操作指南:字符串、哈希、列表詳解

注&#xff1a;此為蒼穹外賣學習筆記 Redis作為高性能的鍵值數據庫&#xff0c;其核心價值來自于豐富的數據結構支持。本文將深入解析字符串&#xff08;String&#xff09;、哈希&#xff08;Hash&#xff09;、**列表&#xff08;List&#xff09;**三大基礎結構的操作命令&…

如何以 9 種方式將照片從 iPhone 傳輸到筆記本電腦

您的 iPhone 可能充滿了以照片和視頻形式捕捉的珍貴回憶。無論您是想備份它們、在更大的屏幕上編輯它們&#xff0c;還是只是釋放設備上的空間&#xff0c;您都需要將照片從 iPhone 傳輸到筆記本電腦。幸運的是&#xff0c;有 9 種方便的方法可供使用&#xff0c;同時滿足 Wind…

如何使用Python從MySQL數據庫導出表結構到Word文檔

在開發和維護數據庫的過程中&#xff0c;能夠快速且準確地獲取表結構信息是至關重要的。本文將向您展示一種簡單而有效的方法&#xff0c;利用Python腳本從MySQL數據庫中提取指定表的結構信息&#xff0c;并將其導出為格式化的Word文檔。此方法不僅提高了工作效率&#xff0c;還…

寫作-- 復合句練習

文章目錄 練習 11. 家庭的支持和老師的指導對學生的學術成功有積極影響。2. 缺乏準備和未能適應通常會導致在挑戰性情境中的糟糕表現。3. 吃垃圾食品和忽視鍛煉可能導致嚴重的健康問題,因此人們應注重保持均衡的生活方式。4. 昨天的大雨導致街道洪水泛濫,因此居民們遷往高地以…

QT使用說明

QT環境準備 推薦Ubuntu平臺上使用&#xff0c;配置簡單&#xff0c;坑少。 Ubuntu 20.04 安裝 sudo apt-get install qt5-default -y sudo apt-get install qtcreator -y sudo apt-get install -y libclang-common-8-dev啟動 qtcreatorHelloWorld 打開 Qt Creator。選擇 …

React 第四十九節 Router中useNavigation的具體使用詳解及注意事項

前言 useNavigation 是 React Router 中一個強大的鉤子&#xff0c;用于獲取當前頁面導航的狀態信息。 它可以幫助開發者根據導航狀態優化用戶體驗&#xff0c;如顯示加載指示器、防止重復提交等。 一、useNavigation核心用途 檢測導航狀態&#xff1a;判斷當前是否正在進行…

列表單獨展開收起同時關閉其余子項的問題優化

如圖所示&#xff0c;當在列表中&#xff0c;需要分別單獨點開子選項時&#xff0c;直接這樣用一個index參數判斷即可&#xff0c;非常簡單方便&#xff0c;只需要滿足點開當前index,然后想同index用null值自動關閉即可

WPF【11_5】WPF實戰-重構與美化(MVVM 實戰)

11-10 【重構】創建視圖模型&#xff0c;顯示客戶列表 正式進入 MVVM 架構的代碼實戰。在之前的課程中&#xff0c; Model 和 View 這部分的代碼重構實際上已經完成了。 Model 就是在 Models 文件夾中看到的兩個文件&#xff0c; Customer 和 Appointment。 而 View 則是所有與…

LangChain-結合魔塔社區modelscope的embeddings實現搜索

首先要安裝modelscope pip install modelscope 安裝完成后測試 from langchain_community.embeddings import ModelScopeEmbeddingsembeddings ModelScopeEmbeddings(model_id"iic/nlp_gte_sentence-embedding_chinese-base")text "這是一個測試句子"…

可定制化貨代管理系統,適應不同業務模式需求!

在全球化貿易的浪潮下&#xff0c;貨運代理行業扮演著至關重要的角色。然而&#xff0c;隨著市場競爭的日益激烈&#xff0c;貨代企業面臨著越來越多的挑戰&#xff1a;客戶需求多樣化、業務流程復雜化、運營成本上升、利潤空間壓縮……這些挑戰迫使貨代企業不斷尋求創新和突破…

Lyra學習筆記2 GFA_AddComponents與ULyraPlayerSpawningManagerComponent

目錄 前言GameFeatureAction_AddComponentsULyraPlayerSpawningManagerComponent緩存所有PlayerStart位置選擇位置 前言 1.以control模式為例 2.比較散&#xff0c;想單獨拿出一篇梳理下Experience的流程 GameFeatureAction_AddComponents 這部分建議看 《InsideUE5》GameFeatu…

進程生命周期

進程生命周期 Linux是多任務操作系統&#xff0c;系統中的每個進程能夠分時復用CPU時間片&#xff0c;通過有效的進程調度策略實現多任務并行執行。進程在被CPU調度運行&#xff0c;等待CPU資源分配以及等待外部事件時會處于不同的狀態。進程狀態如下&#xff1a; 創建狀態&a…

文字轉圖片的字符畫生成工具

軟件介紹 今天要介紹的這款軟件可以將文字轉換成圖片的排列形式&#xff0c;非常適合需要將文字圖形化的場景&#xff0c;建議有需要的朋友收藏。 軟件名稱與用途 這款軟件名為《字符畫大師》&#xff0c;是一款在網吧等場所非常流行的聊天輔助工具&#xff0c;其主要功能就…