讀高性能MySQL(第4版)筆記08_創建高性能索引(上)

来源:https://www.cnblogs.com/lying7/archive/2023/09/14/17699931.html
-Advertisement-
Play Games

1. 索引 1.1. 鍵(key) 1.2. 存儲引擎用於快速找到記錄的一種數據結構 1.3. 當表中的數據量越來越大時,索引對性能的影響愈發重要 1.4. 在數據量較小且負載較低時,缺少合適的索引對性能的影響可能還不明顯 1.5. 索引優化是對查詢性能優化最有效的手段 1.6. 索引能夠輕易將查詢 ...


1. 索引

1.1. 鍵(key)

1.2. 存儲引擎用於快速找到記錄的一種數據結構

1.3. 當表中的數據量越來越大時,索引對性能的影響愈發重要

1.4. 在數據量較小且負載較低時,缺少合適的索引對性能的影響可能還不明顯

1.5. 索引優化是對查詢性能優化最有效的手段

1.6. 索引能夠輕易將查詢性能提高幾個數量級

1.7. “最優”的索引有時比一個“好的”索引性能要好兩個數量級

1.8. 創建一個真正“最優”的索引經常需要重寫查詢

1.9. 可以包含一列或多列的值

1.10. 包含多列,那麼列的順序也十分重要

1.10.1. MySQL只能有效地使用索引的最左首碼列

1.11. 在精妙和複雜的索引面前,無論ORM工具多麼精巧,都不要對其抱太大希望

1.12. 即使是查詢優化技術專家也很難兼顧到各種情況,更別說ORM了

2. 索引的類型

2.1. 在MySQL中,索引是在存儲引擎層而不是伺服器層實現的

2.2. 不同存儲引擎的索引的工作方式並不一樣,也不是所有的存儲引擎都支持所有類型的索引

2.3. 在優化性能的時候,可能需要使用相同的列但順序不同的索引來滿足不同類型的查詢需求

2.4. B-tree索引

2.4.1. 使用B-tree數據結構來存儲數據

2.4.2. 意味著所有的值都是按順序存儲的,並且每一個葉子頁到根的距離相同

2.4.2.1. 按照索引列中的數據大小順序存儲的

2.4.3. 適用於全鍵值、鍵值範圍或鍵首碼查找

2.4.3.1. 鍵首碼查找只適用於根據最左首碼的查找

2.4.4. 能夠加快數據訪問的速度

2.4.4.1. 在查詢某些條件的數據時,存儲引擎不再需要進行全表掃描

2.4.4.2. 通過比較節點頁的值和要查找的值可以找到合適的指針進入下層子節點,這些指針實際上定義了子節點頁中值的上限和下限

2.4.4.3. 最終存儲引擎要麼找到對應的值,要麼該記錄不存在

2.4.5. NDB集群存儲引擎雖然依然使用了BTREE標識,但在其內部實際上使用了T-tree結構存儲這種索引

2.4.6. InnoDB則使用的是B+tree

2.5. 自適應哈希索引

2.5.1. 當InnoDB發現某些索引值被非常頻繁地被訪問時,它會在原有的B-tree索引之上,在記憶體中再構建一個哈希索引

2.5.2. 讓B-tree索引也具備了一些哈希索引的優勢實現非常快速的哈希查找

2.5.3. 完全自動化的,用戶無法進行控制或者配置

2.5.4. 可以通過參數徹底關閉自適應哈希索引這個特性

2.6. 全文索引

2.6.1. FULLTEXT

2.6.2. 查找的是文本中的關鍵詞,而不是直接比較索引中的值

2.6.3. 全文索引和其他幾類索引的匹配方式完全不一樣

2.6.4. 全文索引更類似於搜索引擎做的事情,而不是簡單的WHERE條件匹配

2.6.5. 在相同的列上同時創建全文索引和基於值的B-tree索引並不會有衝突

2.6.6. 全文索引適用於MATCH AGAINST操作,而不是普通的WHERE條件操作

3. 索引優點

3.1. 可以讓伺服器快速地定位到表的指定位置

3.2. 索引大大減少了伺服器需要掃描的數據量

3.3. 索引可以幫助伺服器避免排序和臨時表

3.4. 索引可以將隨機I/O變為順序I/O

4. 高性能的索引策略

4.1. 正確地創建和使用索引是實現高性能查詢的基礎

4.2. 索引的選擇性

4.2.1. 不重覆的索引值(也稱為基數,cardinality)和數據表的記錄總數(#T)的比值,範圍從1/#T到1之間

4.2.2. 索引的選擇性越高則查詢效率越高,因為選擇性高的索引可以讓MySQL在查找時過濾掉更多的行

4.2.3. 唯一索引的選擇性是1,這是最好的索引選擇性,性能也是最好的

4.3. 首碼索引

4.3.1. 一種能使索引更小、更快的有效辦法

4.3.2. 有時候為了提升索引的性能,同時也節省索引空間,可以只對欄位的前一部分字元進行索引

4.3.3. 對於BLOB、TEXT或者很長的VARCHAR類型的列,必須使用首碼索引,因為MySQL並不支持對這些列的完整內容進行索引

4.3.4. 缺點

4.3.4.1. 會降低索引的選擇性

4.3.4.2. MySQL無法使用首碼索引做ORDER BY和GROUP BY操作,也無法使用首碼索引做覆蓋掃描

4.3.5. 既要選擇足夠長的首碼以保證較高的選擇性,同時又不能太長(以便節約空間)

4.3.6. 計算合適的首碼長度的辦法就是計算完整列的選擇性,並使首碼的選擇性接近完整列的選擇性

4.3.7. 只看平均選擇性是不夠的,還有例外的情況,需要考慮最壞情況下的選擇性

4.3.8. 常見的場景是針對很長的十六進位唯一ID使用首碼索引

4.4. 多列索引

4.4.1. 一個常見的錯誤就是,為每列創建獨立的索引,或者按照錯誤的順序創建多列索引

4.4.2. 在多列上獨立地創建多個單列索引,在大部分情況下並不能提高MySQL的查詢性能

4.4.3. 用UNION改寫查詢,往往是最好的辦法

4.5. 選擇合適的索引列順序

4.5.1. 正確的順序依賴於使用該索引的查詢語句

4.5.1.1. 還需要考慮如何更好地滿足排序和分組操作的需要

4.5.2. 索引列的順序意味著索引首先按照最左列進行排序,其次是第二列

4.5.3. 索引可以按照升序或者降序進行掃描,以滿足精確符合列順序的ORDER BY、GROUP BY和DISTINCT等子句的查詢需求

4.5.4. 當不需要考慮排序和分組時,將選擇性最高的列放在前面通常是很好的

4.5.5. 經驗法則考慮的是全局基數和選擇性,而不是某個具體查詢

4.5.6. 性能不只依賴於所有索引列的選擇性(整體基數),也和查詢條件的具體值有關,也就是和值的分佈有關

4.5.7. 經驗法則和推論在多數情況下是有用的,但要註意,不要假設平均情況下的性能也能代表特殊情況下的性能,特殊情況可能會摧毀整個應用的性能

5. 聚簇索引

5.1. 並不是一種單獨的索引類型,而是一種數據存儲方式

5.2. InnoDB的聚簇索引實際上在同一個結構中保存了B-tree索引和數據行

5.3. 聚簇表示數據行和相鄰的鍵值緊湊地存儲在一起

5.4. 因為無法同時把數據行存放在兩個不同的地方,所以一個表只能有一個聚簇索引

5.5. 如果你沒有定義主鍵,InnoDB會選擇一個唯一的非空索引代替

5.6. 如果沒有這樣的索引,InnoDB會隱式定義一個主鍵來作為聚簇索引

5.7. 優點

5.7.1. 以把相互關聯的數據保存在一起

5.7.2. 數據訪問更快

5.7.2.1. 從聚簇索引中獲取數據通常比在非聚簇索引中查找要快

5.7.3. 使用覆蓋索引掃描的查詢可以直接使用頁節點中的主鍵值

5.7.4. 聚簇數據最大限度地提高了I/O密集型應用的性能

5.7.4.1. 如果數據全部都放在記憶體中,則訪問的順序就沒那麼重要了,聚簇索引也就沒什麼優勢了

5.8. 缺點

5.8.1. 插入速度嚴重依賴於插入順序

5.8.2. 更新聚簇索引列的代價很高

5.8.2.1. 會強制InnoDB將每個被更新的行移動到新的位置

5.8.3. 基於聚簇索引的表在插入新行,或者主鍵被更新導致需要移動行的時候,可能面臨頁分裂(page split)的問題

5.8.4. 聚簇索引可能導致全表掃描變慢,尤其是行比較稀疏,或者由於頁分裂導致數據存儲不連續的時候

5.9. 最好避免隨機的(不連續且值的分佈範圍非常大)聚簇索引,特別是對於I/O密集型的應用

5.10. 從性能的角度考慮,使用UUID作為聚簇索引會很糟糕

5.10.1. 主鍵欄位更長

5.10.2. 占用的空間也更大

5.10.2.1. 頁分裂和碎片

5.11. 對於高併發的工作負載,在InnoDB中按主鍵順序插入可能會造成明顯的寫入競爭

5.11.1. 主鍵的上界會成為“熱點”

5.11.2. 所有的插入都發生在這裡,所以併發插入可能導致間隙鎖競爭

5.12. AUTO_INCREMENT鎖機制

5.12.1. 可能需要考慮重新設計表或者應用,或者更改innodb_autoinc_lock_mode配置

6. 二級索引

6.1. 二級索引(非聚簇索引)可能比想象中的要更大,因為二級索引的葉子節點包含了引用行的主鍵列

6.2. 二級索引訪問需要兩次索引查找,而不是一次


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • C#常用的五種定時器分別是: System.Timers.Timer System.Threading.Timer System.Windows.Threading.DispatcherTimer : WPF應用程式 System.Windows.Forms.Timer :WinForm應用程式 S ...
  • .Net Framework使用Autofac實現依賴註入 前言 最近也是找了快2周的工作了,收到的面試邀請也就幾個,然後有個面試題目是用asp.net mvc + Entityframework 做一個學生信息增刪改查系統。因為題目要求了用Entityframework 也就是EF 那也就不上co ...
  • Unity 性能優化之Shader分析處理函數ShaderUtil.HasProceduralInstancing: 深入解析與實用案例 點擊封面跳轉到Unity國際版下載頁面 簡介 在Unity中,性能優化是游戲開發過程中非常重要的一環。其中,Shader的優化對於游戲的性能提升起著至關重要的作用 ...
  • 前言 裝飾模式,英文名稱:Decorator Pattern。我第一次看到這個名稱想到的是另外一個詞語“裝修”,我就說說我對“裝修”的理解吧,大家一定要看清楚,是“裝修”,不是“裝飾”。在房子裝修的過程中,各種功能可以相互組合,來增加房子的功用。類似的,如果我們在軟體系統中,要給某個類型或者對象增加 ...
  • 以下內容為本人的學習筆記,如需要轉載,請聲明原文鏈接 微信公眾號「ENG八戒」https://mp.weixin.qq.com/s/zy6Dmo_b3xMPPEO3HNxuuw 有一段時間沒碰條件變數【condition variable】,快忘了它到底是啥。大概記得,之前是用來寫底層介面,輔助實現 ...
  • 目錄docker鏡像倉庫hub.docker.com無法訪問-解決辦法1 個人鏡像站點2 dockerhub為什麼無法訪問2.1 查看dockerhub實際IP2.2 ping檢測3 鏡像加速3.1 使用國內鏡像加速3.1.1 docker配置:3.1.2 containerd配置:3.2 使用博主 ...
  • 先執行 free -h 查看現在的swap分配情況 執行 swapon -s 查看swap的分區文件 執行 swapoff /dev/dm-1 取消已經掛上的swap文件 現在擴充swap到4G,並將swap文件掛到/vm_memory/swapfile上 先創建/vm_memory/swapfil ...
  • 1、背景描述 出於安全考慮,需要禁止使用root用戶通過ssh遠程登錄Linux 禁用root用戶遠程登錄後,需要提供一個許可權用戶用於ssh遠程登錄 2、創建擁有sudo許可權的用戶 2.1、創建一個普通用戶rain useradd命令用於創建一個用戶, 選項 -m 表示創建用戶的主目錄, -c 表示 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...