mysql索引筆記

這里想整理一下性能優化中用到的東西,先整理一下優化mysql索引中所查閱到的資料吧。

目錄

  • MySQL索引類型詳解
    • 存儲方式區分
      • 1.B+樹索引
      • 2.哈希索引
    • 邏輯區分
      • 1.普通索引
      • 2. 唯一索引
      • 3. 主鍵索引
      • 4. 空間索引
      • 5. 全文索引
    • 實際使用區分
      • 1. 單列索引
      • 2. 多列索引
  • 多表聯查如何建立索引
    • 具體方法與建議
    • 原則與建議
    • 索引優化分析
      • 盡量避免負向查詢
      • 避免使用select *
    • 避免創建冗余索引
  • 如何防止你的索引失效

MySQL索引類型詳解

索引的類型和存儲引擎有關,每種存儲引擎所支持的索引類型不一定完全相同。MySQL 索引可以從存儲方式、邏輯角度和實際使用的角度來進行分類。

存儲方式區分

根據存儲方式的不同,MySQL 中常用的索引在物理上分為 B+樹索引和 HASH 索引兩類,兩種不同類型的索引各有其不同的適用范圍。

1.B+樹索引

B+樹索引又稱為 BTREE 索引,目前大部分的索引都是采用 B+樹索引來存儲的。
MySQL中,索引是在存儲引擎層實現的,不同的存儲引擎支持的索引類型不同,對索引的組織實現方式也不同。我們平時最常使用的是B+樹索引,B+樹是為磁盤或其他存取設備設計的一種平衡查找樹,所有記錄節點按照鍵值大小順序存放在同一層的葉節點上,各葉節點通過指針進行鏈接

B+樹索引是一個典型的數據結構,其包含的組件主要有以下幾個:

  • 葉子節點:包含的條目直接指向表里的數據行。葉子節點之間彼此相連,一個葉子節點有一個指向下一個葉子節點的指針。

  • 分支節點:包含的條目指向索引里其他的分支節點或者葉子節點。

  • 根節點:一個 B+樹索引只有一個根節點,實際上就是位于樹的最頂端的分支節點。

基于這種樹形數據結構,表中的每一行都會在索引上有一個對應值。因此,在表中進行數據查詢時,可以根據索引值一步一步定位到數據所在的行。

其基本特征如下:

  • 非葉節點只存關鍵字以及索引下一層節點的指針
  • 所有葉節點在同一層,包含全部關鍵字和指向記錄的指針,并且按照關鍵字從小到大順序鏈接

可以看到相比一般二叉樹,B+樹的單個節點能存儲更多信息,減少了磁盤 IO 的次數,從而提升了查找速度,而且葉節點形成有序鏈表,非常適合進行范圍查詢。

B+樹索引可以進行全鍵值、鍵值范圍和鍵值前綴查詢,也可以對查詢結果進行 ORDER BY 排序。但 B+樹索引必須遵循左邊前綴原則,要考慮以下幾點約束:

查詢必須從索引的最左邊的列開始。
查詢不能跳過某一索引列,必須按照從左到右的順序進行匹配。
存儲引擎不能使用索引中范圍條件右邊的列。

2.哈希索引

哈希(Hash)一般翻譯為“散列”,也有直接音譯成“哈希”的,就是把任意長度的輸入(又叫作預映射,pre-image)通過散列算法變換成固定長度的輸出,該輸出就是散列值。

哈希索引也稱為散列索引或 HASH 索引。MySQL 目前僅有 MEMORY 存儲引擎和 HEAP 存儲引擎支持這類索引。其中,MEMORY 存儲引擎可以支持 B+樹索引和 HASH 索引,且將 HASH 當成默認索引。

HASH 索引不是基于樹形的數據結構查找數據,而是根據索引列對應的哈希值的方法獲取表的記錄行。哈希索引的最大特點是訪問速度快,但也存在下面的一些缺點:

  • MySQL 需要讀取表中索引列的值來參與散列計算,散列計算是一個比較耗時的操作。也就是說,相對于 B+樹索引來說,建立哈希索引會耗費更多的時間。
  • 不能使用 HASH 索引排序。
  • HASH 索引只支持等值比較,如“=”“IN()”或“”。
  • HASH 索引不支持鍵的部分匹配,因為在計算 HASH 值的時候是通過整個索引值來計算的。

邏輯區分

根據索引的具體用途,MySQL 中的索引在邏輯上分為以下 5 類:

1.普通索引

普通索引是 MySQL 中最基本的索引類型,它沒有任何限制,唯一任務就是加快系統對數據的訪問速度。
普通索引允許在定義索引的列中插入重復值和空值。
創建普通索引時,通常使用的關鍵字是 INDEX 或 KEY。

例 1
下面在 tb表中的 id 字段上建立名為 index_id 的索引。

CREATE INDEX index_id ON tb(id);

2. 唯一索引

唯一索引與普通索引類似,不同的是創建唯一性索引的目的不是為了提高訪問速度,而是為了避免數據出現重復。
唯一索引列的值必須唯一,允許有空值。如果是組合索引,則列值的組合必須唯一。
創建唯一索引通常使用 UNIQUE 關鍵字。

例 2
下面在 tb 表中的 id 字段上建立名為 index_id 的索引,SQL 語句如下:

CREATE UNIQUE INDEX index_id ON tb(id);

3. 主鍵索引

顧名思義,主鍵索引就是專門為主鍵字段創建的索引,也屬于索引的一種。
主鍵索引是一種特殊的唯一索引,不允許值重復或者值為空。
創建主鍵索引通常使用 PRIMARY KEY 關鍵字。不能使用 CREATE INDEX 語句創建主鍵索引。

4. 空間索引

空間索引是對空間數據類型的字段建立的索引,使用 SPATIAL 關鍵字進行擴展。
創建空間索引的列必須將其聲明為 NOT NULL,空間索引只能在存儲引擎為 MyISAM 的表中創建。
空間索引主要用于地理空間數據類型 GEOMETRY。對于初學者來說,這類索引很少會用到。

例 3
下面在 tb 表中的 line 字段上建立名為 index_line 的索引,SQL 語句如下:

CREATE SPATIAL INDEX index_line ON tb(line);

其中,tb 表的存儲引擎必須是 MyISAM,line 字段必須為空間數據類型,而且是非空的。

5. 全文索引

全文索引主要用來查找文本中的關鍵字,只能在 CHAR、VARCHAR 或 TEXT 類型的列上創建。在 MySQL 中只有 MyISAM 存儲引擎支持全文索引。
全文索引允許在索引列中插入重復值和空值。
不過對于大容量的數據表,生成全文索引非常消耗時間和硬盤空間。
創建全文索引使用 FULLTEXT 關鍵字。

例 4
在 tb 表中的 info 字段上建立名為 index_info 的全文索引,SQL 語句如下:

CREATE FULLTEXT INDEX index_info ON tb(info);

其中,index_info 的存儲引擎必須是 MyISAM,info 字段必須是 CHAR、VARCHAR 和 TEXT 等類型。

實際使用區分

索引在邏輯上分為以上 5 類,但在實際使用中,索引通常被創建成單列索引和組合索引。

1. 單列索引

單列索引就是索引只包含原表的一個列。在表中的單個字段上創建索引,單列索引只根據該字段進行索引。
單列索引可以是普通索引,也可以是唯一性索引,還可以是全文索引。只要保證該索引只對應一個字段即可。

例 5
下面在 tb 表中的 address 字段上建立名為 index_addr 的單列索引,address 字段的數據類型為 VARCHAR(20),索引的數據類型為 CHAR(5)。SQL 語句如下:

CREATE INDEX index_addr ON tb(address(5));

這樣,查詢時可以只查詢 address 字段的前 5 個字符,而不需要全部查詢。

2. 多列索引

組合索引也稱為復合索引或多列索引。相對于單列索引來說,組合索引是將原表的多個列共同組成一個索引。多列索引是在表的多個字段上創建一個索引。該索引指向創建時對應的多個字段,可以通過這幾個字段進行查詢。但是,只有查詢條件中使用了這些字段中第一個字段時,索引才會被使用。

例如,在表中的 id、name 和 sex 字段上建立一個多列索引,那么,只有查詢條件使用了 id 字段時,該索引才會被使用。

例 6
下面在 tb 表中的 name 和 address 字段上建立名為 index_na 的索引,SQL 語句如下:

CREATE INDEX index_na ON tb(name,address);

該索引創建好了以后,查詢條件中必須有 name 字段才能使用索引。

提示:一個表可以有多個單列索引,但這些索引不是組合索引。一個組合索引實質上為表的查詢提供了多個索引,以此來加快查詢速度。比如,在一個表中創建了一個組合索引(c1,c2,c3),在實際查詢中,系統用來實際加速的索引有三個:單個索引(c1)、雙列索引(c1,c2)和多列索引(c1,c2,c3)。

索引的優缺點主要體現在:

  • 優勢:可以快速檢索,減少I/O次數,加快檢索速度;根據索引分組和排序,可以加快分組和排序;
  • 劣勢:索引本身也是表,因此會占用存儲空間,一般來說,索引表占用的空間的數據表的1.5倍;索引表的維護和創建需要時間成本,這個成本隨著數據量增大而增大;構建索引會降低數據表的修改操作(刪除,添加,修改)的效率,因為在修改數據表的同時還需要修改索引表;

多表聯查如何建立索引

在 MySQL 數據庫中,設計索引主要是為了提高查詢的效率,降低數據庫的壓力。當我們進行多表查詢時,正確設計索引非常重要。

具體方法與建議

  • 為連接列創建索引:在多表查詢中,連接列通常是性能瓶頸。為這些列創建索引可以顯著提高查詢性能。
  • 考慮表的關聯順序:在JOIN語句中,表的順序可能會影響性能。通常,你應該從具有最小數量的唯一行的表開始,然后逐步添加其他表。
  • 考慮使用覆蓋索引:如果查詢只涉及某些列,并且這些列在索引中包含了所有需要的值,那么可以使用覆蓋索引來提高性能。
  • 考慮聯合索引:如果你有多個列在查詢中經常一起出現,那么可以考慮創建聯合索引。
  • 不要過度索引:雖然索引可以提高性能,但是過多的索引也會增加存儲空間的開銷,并可能降低插入、更新和刪除操作的性能。因此,要平衡索引的使用。

原則與建議

  1. 理解數據和查詢:在設計索引之前,首先需要理解你的數據和查詢。知道哪些列經常被用于 WHERE,ORDER BY,GROUP BY 等子句,以及哪些列經常被 JOIN。這些列可能需要被索引。

  2. 單列索引:如果某一列經常被獨立用于搜索,那么可以為其創建單列索引。例如,如果經常在 user 表上通過 email 列進行搜索,那么可以為 email 列創建索引。

  3. 復合索引:如果有多個列經常一起被用于搜索,那么可以為這些列創建復合索引。復合索引中列的順序對性能有很大影響。在復索引中,索引的順序應該是:最常用于搜索條件的列(高選擇性)放在前面,不經常用于搜索條件的列(低選擇性)放在后面。

  4. 覆蓋索引:如果一個查詢可以通過使用一個索引獲取所有的信息,那么這個索引被稱為覆蓋索引。覆蓋索引可以大大提高查詢性能,因為 MySQL 可以只通過索引就獲取所有需要的信息,而無需回表。

  5. 利用索引合并:MySQL 可以在一次查詢中使用多個索引,這被稱為索引合并。索引合并可以優化復雜的查詢條件,但并不總是最佳選擇。如果可能,應該嘗試創建一個復合索引來替代索引合并。

  6. 避免全表掃描:設計索引的目的之一是避免全表掃描。全表掃描非常低效,應該盡量避免。

這些原則可以幫助你設計索引,但是具體的索引策略還需要根據你的具體情況進行調整。不同的數據、查詢和硬件可能需要不同的索引策略。

下面是一個具體的實驗步驟,可以參考進行操作:

  1. 創建測試數據庫和測試表,插入一些測試數據。
  2. 執行你的查詢,記錄查詢的時間和性能。
  3. 創建一些索引,然后再次執行你的查詢,比較查詢的時間和性能。
  4. 調整索引(例如,改變復合索引的列的順序,添加或刪除某些索引),然后再次執行你的查詢,比較查詢的時間和性能。
  5. 通過比較查詢的時間和性能,找出最佳的索引策略。

索引優化分析

可以通過索引來優化查詢語句的執行效率。MySQL 中,可以使用 EXPLAIN 命令來查看查詢語句的執行計劃,進而優化查詢。如果查詢語句沒有使用索引,可以考慮添加索引或者修改查詢語句的條件,使其能夠利用索引來加快查詢速度。

需要注意的是,雖然索引可以加快查詢速度,但是過多的索引也會影響數據庫的性能,因為索引需要占用存儲空間,并且在修改表數據時也會增加操作的復雜度。因此,在創建索引時需要根據實際情況進行選擇和權衡,避免過度使用索引。

索引的優化是非常必要的,因為索引可以極大地提高數據庫的查詢效率,特別是對于大量數據的表。在建立索引時,需要權衡利弊。一般來說,對于經常被查詢、查詢效率需要提高的列,可以建立索引;而對于不經常被查詢的列,或者存儲空間比較緊張的情況下,可以考慮不建立索引。同時,可以考慮對于一些查詢頻繁但數據更新較少的列建立索引,并定期進行索引維護來保證查詢效率。因此,正確的創建和使用索引是實現高性能查詢的基礎。

盡量避免負向查詢

負向查詢指的是在查詢中使用不等于(<>)或不包含(NOT IN、NOT EXISTS等)的條件,即查詢不滿足某些條件的記錄。負向查詢通常會導致數據庫執行全表掃描,影響查詢性能。

避免使用select *

查詢時盡量不要使用select *,而是只查出需要的字段,因為select * 無法利用覆蓋索引優化,還會為服務器帶來額外的IO、內存和cpu的消耗

避免創建冗余索引

在數據庫中,創建過多的索引會導致查詢性能下降、插入/更新/刪除操作變慢等問題,而創建冗余索引則是其中一種常見的問題。冗余索引指的是已經存在一條索引可以滿足查詢條件,但是又創建了另一條重復的索引。這種索引不僅浪費存儲空間,還會使得數據庫維護索引的代價更大,影響數據庫性能。

避免創建冗余索引的方法包括:

  • 仔細分析查詢需求,只創建必要的索引。
  • 定期檢查數據庫中的索引,及時刪除冗余的索引。
  • 盡量避免創建覆蓋索引,因為它可能包含多個不必要的字段。

需要注意的是,索引的設計并不是一成不變的,需要根據具體的業務需求和數據特征不斷進行調整和優化。

如何防止你的索引失效

  1. 使用多列作為索引,需要遵循最左前綴匹配原則(查詢從索引的最左前列開始并且不跳過索引中的列)
  2. 不在索引列上做任何操作,例如:計算、函數、自動or手動的類型轉換,會導致索引失效而轉向全表掃描
    如果你對列進行了(+,-,*,/,!)、函數、or運算,那么都將不會走索引
  3. 盡量使用索引覆蓋(只訪問索引列的查詢),減少select * ,覆蓋索引能減少回表次數
  4. mysql在使用不等于(!=或者<>)的時候無法使用索引會導致全表掃描
  5. like以通配符開頭(%abc),mysql索引會失效變成全表掃描的操作
  6. 字符串不加單引號會導致索引失效(可能發生了索引列的隱式轉換)
    例如 select * from tb where name = name;

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

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

相關文章

GD 32中斷系統實現

1.0 中斷的概念 中斷&#xff1a;簡單來說就是打斷的意思&#xff0c;在計算機系統中CPU在執行一個操作的時候&#xff0c;有一個比當前任務更為緊急的任務需要執行,cpu暫停當前任務轉而去執行更為緊急任務的操作&#xff0c;執行完更為緊急任務之后再返回來執行原來未執行完的…

SRS流媒體源碼解析--service

本文主要解析一下SRS3.0 service部分源碼&#xff0c;主要和srs_service_st模塊。 srs_service_st 模塊包含了網絡服務的基礎實現&#xff0c;特別是與套接字&#xff08;sockets&#xff09;和網絡通信相關的功能。主要功能和特點包括&#xff1a; &#xff08;1&#xff0…

高鐵站客運樞紐IPTV電視系統-鹽城高鐵站西廣場IP電視系統應用淺析

高鐵站客運樞紐IPTV電視系統-鹽城高鐵站西廣場IP電視系統應用淺析 由北京海特偉業科技有限公司任洪卓于2024年7月9日發布 隨著科技的飛速發展&#xff0c;特別是“互聯網”戰略的深入推進&#xff0c;高鐵站客運樞紐的信息化建設成為提升服務質量、增強乘客體驗的重要手段。鹽…

代碼隨想錄算法訓練營:29/60

非科班學習算法day29 | LeetCode134:加油站 &#xff0c;Leetcode135:分發糖果 &#xff0c;Leetcode860:檸檬水找零 介紹 包含LC的兩道題目&#xff0c;還有相應概念的補充。 相關圖解和更多版本&#xff1a; 代碼隨想錄 (programmercarl.com)https://programmercarl.com/…

IT專業高考假期入門指南

IT領域預習指南&#xff1a;開啟未來科技之旅 一、確定興趣方向 IT領域廣闊&#xff0c;涵蓋軟件開發、網絡安全、數據分析、人工智能等多個方向。首先&#xff0c;明確自己的興趣所在&#xff0c;這將決定你后續學習的重點。比如&#xff0c;如果你對構建應用程序感興趣&…

【1.3】動態規劃-解碼方法

一、題目 一條包含字母A-Z的消息通過以下映射進行了編碼&#xff1a; A -> 1 B -> 2 ... Z -> 26 要解碼已編碼的消息&#xff0c;所有數字必須基于上述映射的方法&#xff0c;反向映射回字母&…

新能源汽車充電站遠程監控系統S275鋇錸技術無線RTU

新能源汽車充電站的遠程監控系統在現代城市基礎設施中扮演著至關重要的角色&#xff0c;而鋇錸技術的S275無線RTU作為一款先進的物聯網數據監測采集控制短信報警終端&#xff0c;為充電站的安全運行和高效管理提供了強大的技術支持。 技術特點和功能 鋇錸S275采用了基于UCOSI…

Android11 窗口動畫

窗口進入動畫 應用端窗口繪制完成之后&#xff0c;調用finshDraw告知WMS&#xff0c;WMS這邊最后就會調用WindowSurfacePlacer的performSurfacePlacement方法&#xff0c;最終調用到 WindowStateAnimator的commitFinishDrawingLocked方法 //frameworks/base/services/core/jav…

JS進階-深入對象

學習目標&#xff1a; 掌握深入對象 學習內容&#xff1a; 創建對象三種方式構造函數實例成員&靜態成員 創建對象三種方式&#xff1a; 利用對象字面量創建對象 const o {name: 佩奇}利用new Object創建對象 const obj new Object({ uname: 雪碧寶寶 })console.log(obj…

OJhelper一款幫助你獲取各大oj信息的軟件

項目地址 應用功能 目前應用支持&#xff1a;查詢、自定義、收藏各大oj比賽信息&#xff0c;跳轉比賽界面。查詢各大oj的Rating分以及題量&#xff0c;查看題量餅狀圖。 應用環境 windows和安卓端 應用預覽&#xff1a; 維護概況 后期會提供持續更新&#xff0c;具體可以…

7.9數據結構

思維導圖 作業 doubleloop.h #ifndef __DOUBLELOOP_H__ #define __DOUBLELOOP_H__#include <stdio.h> #include <stdlib.h>typedef int datatype; typedef struct node {union{int len;datatype data;};struct node *pri;//前驅指針struct node *next;//后繼指針…

全終端自動化測試框架wyTest

突然有一些覺悟&#xff0c;程序猿不能只會吭哧吭哧的低頭做事&#xff0c;應該學會怎么去展示自己&#xff0c;怎么去宣傳自己&#xff0c;怎么把自己想做的事表述清楚。 于是&#xff0c;這兩天一直在整理自己的作品&#xff0c;也為接下來的找工作多做點準備。接下來…

Linux | 安裝lb-toolkits 1.2.4庫

Linux | 安裝 lb-toolkits 最近又需要下載葵花的數據&#xff0c;之前分享過一次代碼。今天發現之前的環境不小心被我刪了&#xff0c;而運行相關的代碼需要安裝lb-toolkits這個庫&#xff0c;今天正好記錄了一下安裝lb-toolkits的過程。 這里安裝的版本是1.2.4&#xff0c;別…

windows USB 設備驅動開發-發送MDL和錯誤恢復

USB 驅動程序可以在堆棧中使用鏈接式 MDL 功能發送數據&#xff0c;并且USB驅動的客戶端可以將傳輸緩沖區作為 MDL 結構鏈發送。 大多數 USB 主機控制器要求傳輸緩沖區幾乎是連續的。 幾乎連續意味著緩沖區可以開始和結束頁中的任意位置&#xff0c;但緩沖區的其余部分必須在頁…

53-4 內網代理6 - frp搭建三層代理

前提:53-3 內網代理5 - frp搭建二級代理-CSDN博客 三級網絡代理 在辦公區入侵后,發現需要進一步滲透核心區網絡(192.168.60.0/24),并登錄域控制器的遠程桌面。使用FRP在EDMZ區、辦公區與核心區之間建立三級網絡的SOCKS5代理,以便訪問核心區的域控制器。 VPS上的FRP服…

海豚調度器(DolphinScheduler)修改時區為東八區

海豚調度器設置了定時&#xff0c;執行的時間和設置時間不同&#xff0c;后來排查發現是時區問題。可以用下面方法和步驟來修改&#xff1a; 修改DolphinScheduler服務器時區 登錄服務器&#xff1a;首先&#xff0c;通過SSH或其他方式登錄到運行DolphinScheduler服務的服務器…

壓縮感知3——重構算法正交匹配追蹤算法

算法流程 問題的實質是&#xff1a;AX Y 求解&#xff08;A是M維&#xff0c;Y是N維且N>>M并且稀疏度K<M&#xff09;明顯X有無窮多解&#xff0c;重構過程是M次采樣得到的采樣值升維的過程。OMP算法的具體步驟&#xff1a;(1)用X表示信號&#xff0c;初始化殘差e0 …

計算給定數字的階乘

1 問題 計算給定數字的階乘. 2 方法 使用while循環。使用for循環。使用函數。 通過實驗、實踐等證明提出的方法是有效的&#xff0c;是能夠解決開頭提出的問題。 代碼清單 1 使用while循環numberint(input(請輸入一個數字:))factorial1i1while i<number: factorialfactor…

【論文速讀】| JADE:用于大語言模型的基于語言學的安全評估平臺

本次分享論文&#xff1a;JADE : A Linguistics-based Safety Evaluation Platform for Large Language Models 基本信息 原文作者&#xff1a;Mi Zhang, Xudong Pan, Min Yang 作者單位&#xff1a;Whitzard-AI, System Software and Security Lab Fudan University 關鍵…

AWS Glue 與 Amazon Redshift 的安全通信配置

1. 引言 在 AWS 環境中,確保服務間的安全通信至關重要。本文將探討 AWS Glue 與 Amazon Redshift 之間的安全通信配置,特別是為什么需要特定的安全組設置,以及如何正確實施這些配置。 2. 背景 AWS Glue:全托管的 ETL(提取、轉換、加載)服務Amazon Redshift:快速、完全…