主頁 > 資料庫 > MySQL學習筆記-索引

MySQL學習筆記-索引

2023-04-15 08:39:47 資料庫

索引

索引(index)是幫助MySQL高效獲取資料的資料結構(有序),在資料之外,資料庫系統還維護著滿足特定查找演算法的資料結構,這些資料結構以某種方式參考(指向)資料,這樣就可以在這些資料結構上實作高級查找演算法,這種資料結構就是索引,

  • 無索引的查找:全表掃描(將整張表遍歷一遍),性能極低,

  • 有索引的查找:資料庫系統在存盤資料的同時會維護一種資料結構(如二叉樹),當需要查找時,利用該資料結構進行查找,性能較高,

  • 索引的優缺點

image-20230403104353418

一. 索引結構

MySQL的索引是在存盤引擎層實作的,不同的存盤引擎有不同的結構,

image-20230403104609783

  • 索引在存盤引擎中的支持情況

image-20230403104744836

  • 平常所說的索引,如果沒有特別指明,一般都是說B+樹結構組織的索引

1. B+樹

1.1 二叉樹

image-20230403111008578

  • 一種經典的資料結構,

  • 二叉樹的兩個缺點:

    • 順序存盤二叉樹時,會形成一條鏈表,二叉樹的深度很大,效率很低,
    • 二叉樹的度不大于2,在資料庫中存有大量資料的時候深度很大,效率很低,

1.2 紅黑樹

image-20230403111342398

  • 一種自平衡的特殊二叉樹,

  • 可以解決二叉樹可能形成鏈表的缺點,但是依舊存在資料量大時深度很大的問題,

1.3 B樹(平衡多路查找樹)

image-20230403111959716

  • 一種自平衡的樹,可以解決二叉樹的兩個缺點,
  • 一個節點可以擁有兩個以上的子節點,

1.4 B+樹

image-20230403112217055

  • B樹的變種,
  • B+樹與B樹的區別:
    • 所有的元素都會出現在葉子節點,
    • 葉子節點形成了一條單向鏈表,

1.5 MySQL中的B+樹

image-20230403112420607

  • 在MySQL中,對B+樹進行了優化,在原有基礎上,葉子節點改為了雙向回圈鏈表,提高區間訪問的性能,

2. Hash

哈希索引就是采用一定的Hash演算法,將鍵值換算成新的Hash值,映射到對應的槽位上,然后存盤在Hash表中,

如果兩個(或多個)鍵值映射到同一個槽位上,產生了Hash沖突,可以通過鏈表解決,

image-20230403112944770

2.1 Hash索引的特點

  1. 只能用于對等比較(=,in),不支持范圍查詢(between,>,<,...),
  2. 無法利用索引完成排序操作,
  3. 查詢效率高,通常只需要一次檢索(不出現hash沖突),效率高于B+樹,

2.2 存盤引擎支持

在MySQL中,支持hash索引的是Memory引擎,而InnoDB中具有自適應hash功能,hash索引是存盤引擎根據B+樹索引在指定條件下自動構建的,

二. 索引分類

image-20230403113658879

  • 在InnoDB存盤引擎中,根據索引的存盤形式,又可以分為以下兩種:

image-20230403113904289

  • 聚集索引的選取規則:
    • 如果存在主鍵,主鍵索引就是聚集索引,
    • 如果不存在主鍵,將適用第一個唯一(UNIQUE)索引作為聚集索引,
    • 如果不存在主鍵,或沒有合適的唯一索引,則InnoDB會自動生成一個rowid作為隱藏的聚集索引,
  • 聚集索引和二級索引的示意圖:

image-20230403114330417

  • 在查找時,先走二級索引,找到對應的主鍵后,再走聚集索引,找到對應的整個行,(回表查詢)

三. 索引語法

1. 創建索引

create [unique|fulltext] index {索引名} on {表名} ({欄位名},...);
  • unique 唯一索引 |fulltext 全文索引 |不加這兩個則說明是常規索引,
  • 一個索引可以關聯多個欄位,如果一個索引只關聯一個欄位,叫單列索引,如果關聯多個欄位,叫聯合索引(組合索引)
  • 聯合索引的欄位順序是有講究的,
  • 索引名一般的命名規則:idx _ 表名 _ 欄位名

2. 查看索引

show index form {表名};

3. 洗掉索引

drop index {索引名} on {表名};

四. SQL性能分析

做性能分析是為了做SQL優化,SQL主要是做查詢優化,因為查詢操作比增刪改多,查詢優化的關鍵在于索引,

1. SQL執行頻率

# 查看當前資料庫的增刪改查的訪問頻次
show global status like 'Com_______';
# 模糊匹配'Com'后面是7個下劃線

image-20230411153543375

  • 根據執行頻率來判斷SQL優化需要在哪方面進行,也就是說這個資料庫哪個操作頻率高就優化哪個操作,

2. 慢查詢日志

慢查詢日志記錄了所有執行時間超過制定引數 (long_query_time,單位:秒,默認10秒) 的所有sql陳述句的日志

慢查詢日志用于找到執行慢的sql陳述句,進行針對性優化,

2.1 開啟慢查詢日志

MySQL的慢查詢日志默認沒有開啟,需要在MySQL的組態檔(/etc/my.cnf) 中配置,

  • 查詢是否開啟
show variables like 'slow_query_log';
  • 開啟慢查詢日志

在MySQL的組態檔(/etc/my.cnf) 中配置如下資訊:

# 開啟MySQL慢查詢日志開關
show_query_log = 1
# 設定慢查詢日志的時間為2秒,SQL陳述句執行時間超過2秒就會被記錄
long_query_time = 2

配置完畢后,需要重啟服務器,

# 重啟服務器
systemctl restart mysqld

2.2 查看慢查詢日志

# 慢查詢日志存放地址 Linux下
/var/lib/mysql/localhost-slow.log

image-20230411155034464

3. profile詳情

Show profiles 能夠在做SQL優化時幫助我們了解時間都耗費到哪里去了,

3.1 查看MySQL是否支持profile操作

select @@have_profiling;

3.2 打開profile開關

# 查看是否打開
select @@profiling;

# 打開profile開關
set [session|global] profiling = 1;
  • profile默認是關閉的,

  • [session|global] 可以指定是會話級別的還是全域的,

3.3 查看profile詳情

# 查看每一條SQL的耗時基本情況
show profiles;

# 查看指定query_id的SQL陳述句各個階段的耗時情況
show profile for query query_id;

# 查看指定query_id的SQL陳述句CPU的使用情況
show profile cup for query query_id;
  • query_id指的是在profiles中的某一條指令的id,可以在show profiles中看到,

4. explain執行計劃

explain 或者 desc命令獲取MySQL如何執行select陳述句的資訊,包括在select陳述句執行程序中表如何連接和連接的順序,

# 直接在select陳述句之前加上關鍵字explain/desc
explain select {欄位串列} from {表名} where {條件};
  • explain執行計劃各欄位含義

image-20230411163705430

image-20230411163917602

五. 索引使用

1. 最左前綴法則

  • 如果索引了多列(聯合索引),要遵循最左前綴法則,最左前綴法則是指查詢從索引的最左列開始,并且不跳過索引中的列,

  • 如果跳躍某一列,索引將部分失效(后面的欄位索引失效)

  • 查詢時左邊欄位存在即符合最左前綴法則,不管它在代碼中的位置,

2. 范圍查詢

  • 聯合索引中,出現范圍查詢(> , <),范圍查詢右側的列索引失效
  • 用(>= , <=)不會出現失效情況,

3. 索引列運算

  • 不要在索引列上進行運算操作,否則索引將失效

4. 字串不加引號

  • 字串型別欄位使用時,不加引號,索引將失效

5. 模糊查詢

  • 如果是尾部進行模糊查詢,索引不會失效;如果是頭部進行模糊查詢,索引會失效

6. or連接的條件

  • 用or分割開的條件,如果or前的條件中的列有索引,二后面的列沒有索引,那么涉及的索引都不會被用到
  • 只要把沒有索引的建立一個索引就可以解決失效問題,

7. 資料分布影響

  • 如果MySQL評估使用索引比全表更慢,則不使用索引

8. SQL提示

SQL提示是優化資料庫的一個重要手段,在SQL陳述句中加入一些人為的提示來達到優化操作的目的,

8.1 use index

  • 使用指定索引(建議)
select * from {表名} use index({索引名}) where...;

8.2 ignore index

  • 不使用某個索引
select * from {表名} ignore index({索引名}) where...;

8.3 force index

  • 使用指定索引(必須)
select * from {表名} force index({索引名}) where...;

9. 覆寫索引

  • 盡量使用覆寫索引(查詢使用了索引,并且需要回傳的列,在該索引中已經全部能夠找到),減少使用select *,

  • 使用覆寫索引和沒有使用覆寫索引,在explain中的Extra列有不一樣的提示:

    • (沒使用)using index condition : 查找使用了索引,但是需要回表查詢資料,
    • (使用了)using where; using index : 查找使用了索引,但是需要的資料都在索引列中能夠找到,所以不需要回表查詢資料,
  • 覆寫索引直接在二級索引中獲取了回傳所需的所有資料,所以不需要回表查詢,查詢速度快,

  • 如果不是覆寫查詢,在二級索引中查詢到資料后,還需要拿到對應資料的主鍵,到聚焦索引中查詢行資料,這就叫回表查詢,所以速度慢,

10. 前綴索引

當欄位型別為字串時,有時候需要存盤很長的字串,如果建立索引,索引會變得很大,浪費大量磁盤IO,影響查詢效率,

此時可以只用字串的一部分前綴來建立索引(前綴索引),可以大大節約索引空間,從而提高效率,

10.1 創建前綴索引

create index {索引名} on {表名}({欄位名}({前綴的字符數}));

10.2 前綴長度的選擇

  • 可以根據索引的選擇性來決定,

  • 選擇性:不重復的索引值和資料表的記錄總數的比值,索引選擇性越高,效率越高,唯一索引的選擇性是1,是性能最好的,

  • 求選擇性:

select count(distinct substring({欄位名},1,{截取長度}))/count(*) from {表名};

11. 單列索引和聯合索引

  • 單列索引:一個索引只包含單個列

  • 聯合索引:一個索引包含了多個列

  • 在業務場景中,如果存在多個查詢條件,考慮針對查詢欄位建立索引時,建議使用聯合索引,

  • 聯合索引的存盤結構:

image-20230414171408279

六. 索引設計原則

image-20230414171642246

轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/550167.html

標籤:MySQL

上一篇:openEuler、龍蜥Anolis、統信UOS系統下編譯GreatSQL二進制包

下一篇:全面數字化時代,國有大型銀行如何走好金融創新之路?

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • GPU虛擬機創建時間深度優化

    **?桔妹導讀:**GPU虛擬機實體創建速度慢是公有云面臨的普遍問題,由于通常情況下創建虛擬機屬于低頻操作而未引起業界的重視,實際生產中還是存在對GPU實體創建時間有苛刻要求的業務場景。本文將介紹滴滴云在解決該問題時的思路、方法、并展示最終的優化成果。 從公有云服務商那里購買過虛擬主機的資深用戶,一 ......

    uj5u.com 2020-09-10 06:09:13 more
  • 可編程網卡芯片在滴滴云網路的應用實踐

    **?桔妹導讀:**隨著云規模不斷擴大以及業務層面對延遲、帶寬的要求越來越高,采用DPDK 加速網路報文處理的方式在橫向縱向擴展都出現了局限性。可編程芯片成為業界熱點。本文主要講述了可編程網卡芯片在滴滴云網路中的應用實踐,遇到的問題、帶來的收益以及開源社區貢獻。 #1. 資料中心面臨的問題 隨著滴滴 ......

    uj5u.com 2020-09-10 06:10:21 more
  • 滴滴資料通道服務演進之路

    **?桔妹導讀:**滴滴資料通道引擎承載著全公司的資料同步,為下游實時和離線場景提供了必不可少的源資料。隨著任務量的不斷增加,資料通道的整體架構也隨之發生改變。本文介紹了滴滴資料通道的發展歷程,遇到的問題以及今后的規劃。 #1. 背景 資料,對于任何一家互聯網公司來說都是非常重要的資產,公司的大資料 ......

    uj5u.com 2020-09-10 06:11:05 more
  • 滴滴AI Labs斬獲國際機器翻譯大賽中譯英方向世界第三

    **桔妹導讀:**深耕人工智能領域,致力于探索AI讓出行更美好的滴滴AI Labs再次斬獲國際大獎,這次獲獎的專案是什么呢?一起來看看詳細報道吧! 近日,由國際計算語言學協會ACL(The Association for Computational Linguistics)舉辦的世界最具影響力的機器 ......

    uj5u.com 2020-09-10 06:11:29 more
  • MPP (Massively Parallel Processing)大規模并行處理

    1、什么是mpp? MPP (Massively Parallel Processing),即大規模并行處理,在資料庫非共享集群中,每個節點都有獨立的磁盤存盤系統和記憶體系統,業務資料根據資料庫模型和應用特點劃分到各個節點上,每臺資料節點通過專用網路或者商業通用網路互相連接,彼此協同計算,作為整體提供 ......

    uj5u.com 2020-09-10 06:11:41 more
  • 滴滴資料倉庫指標體系建設實踐

    **桔妹導讀:**指標體系是什么?如何使用OSM模型和AARRR模型搭建指標體系?如何統一流程、規范化、工具化管理指標體系?本文會對建設的方法論結合滴滴資料指標體系建設實踐進行解答分析。 #1. 什么是指標體系 ##1.1 指標體系定義 指標體系是將零散單點的具有相互聯系的指標,系統化的組織起來,通 ......

    uj5u.com 2020-09-10 06:12:52 more
  • 單表千萬行資料庫 LIKE 搜索優化手記

    我們經常在資料庫中使用 LIKE 運算子來完成對資料的模糊搜索,LIKE 運算子用于在 WHERE 子句中搜索列中的指定模式。 如果需要查找客戶表中所有姓氏是“張”的資料,可以使用下面的 SQL 陳述句: SELECT * FROM Customer WHERE Name LIKE '張%' 如果需要 ......

    uj5u.com 2020-09-10 06:13:25 more
  • 滴滴Ceph分布式存盤系統優化之鎖優化

    **桔妹導讀:**Ceph是國際知名的開源分布式存盤系統,在工業界和學術界都有著重要的影響。Ceph的架構和演算法設計發表在國際系統領域頂級會議OSDI、SOSP、SC等上。Ceph社區得到Red Hat、SUSE、Intel等大公司的大力支持。Ceph是國際云計算領域應用最廣泛的開源分布式存盤系統, ......

    uj5u.com 2020-09-10 06:14:51 more
  • es~通過ElasticsearchTemplate進行聚合~嵌套聚合

    之前寫過《es~通過ElasticsearchTemplate進行聚合操作》的文章,這一次主要寫一個嵌套的聚合,例如先對sex集合,再對desc聚合,最后再對age求和,共三層嵌套。 Aggregations的部分特性類似于SQL語言中的group by,avg,sum等函式,Aggregation ......

    uj5u.com 2020-09-10 06:14:59 more
  • 爬蟲日志監控 -- Elastc Stack(ELK)部署

    傻瓜式部署,只需替換IP與用戶 導讀: 現ELK四大組件分別為:Elasticsearch(核心)、logstash(處理)、filebeat(采集)、kibana(可視化) 下載均在https://www.elastic.co/cn/downloads/下tar包,各組件版本最好一致,配合fdm會 ......

    uj5u.com 2020-09-10 06:15:05 more
最新发布
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:33:24 more
  • MySQL中binlog備份腳本分享

    關于MySQL的二進制日志(binlog),我們都知道二進制日志(binlog)非常重要,尤其當你需要point to point災難恢復的時侯,所以我們要對其進行備份。關于二進制日志(binlog)的備份,可以基于flush logs方式先切換binlog,然后拷貝&壓縮到到遠程服務器或本地服務器 ......

    uj5u.com 2023-04-20 08:28:06 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:27:27 more
  • 快取與資料庫雙寫一致性幾種策略分析

    本文將對幾種快取與資料庫保證資料一致性的使用方式進行分析。為保證高并發性能,以下分析場景不考慮執行的原子性及加鎖等強一致性要求的場景,僅追求最終一致性。 ......

    uj5u.com 2023-04-20 08:26:48 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:26:35 more
  • 云時代,MySQL到ClickHouse資料同步產品對比推薦

    ClickHouse 在執行分析查詢時的速度優勢很好的彌補了MySQL的不足,但是對于很多開發者和DBA來說,如何將MySQL穩定、高效、簡單的同步到 ClickHouse 卻很困難。本文對比了 NineData、MaterializeMySQL(ClickHouse自帶)、Bifrost 三款產品... ......

    uj5u.com 2023-04-20 08:26:29 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:25:13 more
  • Redis 報”OutOfDirectMemoryError“(堆外記憶體溢位)

    Redis 報錯“OutOfDirectMemoryError(堆外記憶體溢位) ”問題如下: 一、報錯資訊: 使用 Redis 的業務介面 ,產生 OutOfDirectMemoryError(堆外記憶體溢位),如圖: 格式化后的報錯資訊: { "timestamp": "2023-04-17 22: ......

    uj5u.com 2023-04-20 08:24:54 more
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:24:03 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:23:11 more