讀高性能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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...