欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

MySQL聚簇索引、非聚簇索引、覆蓋索引詳解

 更新時間:2024年12月25日 09:27:25   作者:高錳酸鉀_  
這篇文章詳細(xì)介紹了聚簇索引、非聚簇索引和覆蓋索引的概念,并通過圖示和實例說明了索引查找的過程和回表查詢的概念,同時,文章也提到了覆蓋索引的優(yōu)點和弊端,并給出了適用場景

聚簇索引、非聚簇索引、覆蓋索引

本篇將帶你搞懂什么是聚簇索引、非聚簇索引、覆蓋索引,并且通過畫圖的方式了解索引查找的過程,明白什么是回表查詢

索引(Index)是數(shù)據(jù)庫中一種用于快速查找和訪問表中數(shù)據(jù)的結(jié)構(gòu),它類似于書的目錄,通過索引可以快速定位到目標(biāo)數(shù)據(jù),而無需遍歷整個表,索引的存在可以顯著提高查詢速度,尤其是在處理大量數(shù)據(jù)時

MySQL中默認(rèn)使用索引的數(shù)據(jù)結(jié)構(gòu)是B+樹,詳細(xì)可以參考:MySQL索引為什么是B+數(shù)

那什么又是聚簇索引、非聚簇索引、覆蓋索引?

聚簇索引

聚簇索引也叫聚集索引,是一種將數(shù)據(jù)行的物理存儲順序與索引的邏輯順序相同的索引,換句話說,數(shù)據(jù)是直接存儲在索引的葉子節(jié)點中,通過主鍵查找到某一行數(shù)據(jù),這一行數(shù)據(jù)的全部內(nèi)容都存放在這個葉子節(jié)點中,聚簇索引必須有,而且只能有一個。

以下面這個表為例:

idnameusernameage
1001張三zhangsan20
1002李四lisi18
1003王九wangjiu35
1004趙六zhaoliu22
1005王八wangba17
1006李白libai40
1007杜甫dufu33

以主鍵id來為其生成一個簡單的B+樹索引為:

這個利用主鍵字段來生成的索引就是一個聚簇索引,當(dāng)我們通過id查找某一個用戶時,通過查找算法,找到了他所在的葉子節(jié)點,那么在這個葉子節(jié)點中,就存放了該用戶的整行數(shù)據(jù),包括姓名、賬號、年齡:

如果定義了主鍵,MySQL會自動將主鍵列作為聚簇索引;如果沒有主鍵,MySQL會選擇一個唯一非空索引;如果沒有唯一索引,MySQL會生成一個隱藏的rowid作為主鍵來生成聚簇索引

非聚簇索引

相比于聚簇索引,非聚簇索引也叫二級索引,它的葉子節(jié)點存儲的是索引列的值以及指向?qū)嶋H數(shù)據(jù)行的指針(或主鍵值),而不是完整的數(shù)據(jù)行,也就是說,非聚簇索引的葉子節(jié)點中,存放的不再是整行數(shù)據(jù),而是該行數(shù)據(jù)的主鍵

當(dāng)我們?yōu)樯媳斫⑺饕龝r,使用的不是id,而是username

默認(rèn)會使用字母順序來進(jìn)行排序,但是其葉子節(jié)點中存儲的不再是整行數(shù)據(jù),而是該行數(shù)據(jù)的索引值

回表查詢

回表查詢是數(shù)據(jù)庫查詢中的一個術(shù)語,指的是在使用非聚簇索引(或普通索引)時,數(shù)據(jù)庫查詢引擎需要通過索引查找到對應(yīng)的行號(或主鍵值),然后再回到表中查找完整的行數(shù)據(jù)的過程

以上表為例,我們想要查詢usernamezhaoliu的用戶全部信息:

select * from user where username = 'zhaoliu'

1.此時回先到username的非聚簇索引中去查找

通過username的比對查找,找到了zhaoliu所在的葉子節(jié)點,但是葉子節(jié)點中并沒有我們需要的全部用戶信息,只有該用戶的主鍵值id

2.這時就會拿著id去聚簇索引中比對查找

找到該用戶的葉子節(jié)點,再把葉子節(jié)點中的整行數(shù)據(jù)返回

回表查詢增加了 I/O 操作,尤其是表數(shù)據(jù)量大時會顯著降低性能,所以我們在設(shè)計索引時,盡量要避免出現(xiàn)回表查詢

當(dāng)查詢的字段較少且頻率較高時,建議使用覆蓋索引優(yōu)化查詢

覆蓋索引

覆蓋索引(Covering Index) 是一種索引優(yōu)化技術(shù),指的是查詢所需的所有字段都可以直接從索引中獲取,無需再回表查詢。這種方式可以顯著提高查詢性能,因為避免了回表操作

也就是說,當(dāng)我們建立索引時,不再使用單一字段來建立索引,而是包含多個字段,這樣在利用索引進(jìn)行查詢信息時,葉子節(jié)點中可以包含全部的所需數(shù)據(jù),不必再到其他索引中查詢,因此可以避免回表查詢

比如之前以username建立的索引,如果我們不查詢用戶的全部數(shù)據(jù),而是只需要返回usernameid

select id,name from user where name = 'zhangsan'

username建立的索引中已經(jīng)包含了想要的全部數(shù)據(jù):usernameid,因此不需要再去查詢其他的索引,這就是覆蓋索引

在建立索引時,可以設(shè)置多字段建立索引:

CREATE INDEX idx_name_age ON users(name, age)

這樣索引的葉子節(jié)點中就存放了更多的數(shù)據(jù)

當(dāng)我們查詢所需要的信息nameage時,索引 idx_name_age 包含 nameage,因此查詢所需的字段完全覆蓋,無需回表

SELECT name, age FROM users WHERE name = 'John'

但是覆蓋索引也有一些弊端:

  • 1.增加存儲開銷
  • 索引存儲需要額外空間,字段越多,索引越大。
  • 2.寫性能受影響
  • 插入、更新、刪除操作需要同時更新覆蓋索引,導(dǎo)致寫入開銷增加。
  • 3.適用場景有限
  • 覆蓋索引適用于查詢固定字段的場景,但無法應(yīng)對動態(tài)字段需求。

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • MySQL錯誤:You can‘t specify target table ‘xxx‘ for update in FROM clause的解決方案

    MySQL錯誤:You can‘t specify target table&n

    在編寫MySQL的UPDATE或DELETE語句時,如果子查詢中直接引用了要操作的目標(biāo)表,可能會遇到一個常見的錯誤:You can’t specify target table ‘xxx’ for update in FROM clause,這個錯誤讓許多開發(fā)者感到困惑,本文將深入分析其原因,并提供多種解決方案,
    2025-02-02
  • CentOS 7下mysql 5.7 安裝教程

    CentOS 7下mysql 5.7 安裝教程

    這篇文章主要為大家詳細(xì)介紹了CentOS 7下mysql 5.7 安裝教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-08-08
  • 分享下mysql各個主要版本之間的差異

    分享下mysql各個主要版本之間的差異

    因為mysql的版本較多,而且又被oracle公司收購,所有很多朋友不是很清楚各個版本的區(qū)別,這里簡單介紹下,方便需要的朋友
    2013-06-06
  • ubuntu系統(tǒng)中Mysql ERROR 1045 (28000): Access denied for user root@ localhost問題的解決方法

    ubuntu系統(tǒng)中Mysql ERROR 1045 (28000): Acces

    這篇文章主要介紹了ubuntu系統(tǒng)安裝mysql登陸提示 解決Mysql ERROR 1045 (28000): Access denied for user root@ localhost問題,需要的朋友可以參考下
    2017-05-05
  • 一篇文章弄懂MySQL查詢語句的執(zhí)行過程

    一篇文章弄懂MySQL查詢語句的執(zhí)行過程

    這篇文章主要給大家介紹了如何通過一篇文章弄懂MySQL查詢語句的執(zhí)行過程的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • 詳解MySQL的主鍵查詢?yōu)槭裁催@么快

    詳解MySQL的主鍵查詢?yōu)槭裁催@么快

    這篇文章主要介紹了想借MySQL的主鍵查詢?yōu)槭裁催@么快,下面根據(jù)主題展開的內(nèi)容有InnoDB行格式、InnoDB頁和InnoDB行格式等詳細(xì)內(nèi)容,下面相關(guān)介紹需要的小伙伴可以參考一下
    2022-04-04
  • 使用mysql記錄從url返回的http GET請求數(shù)據(jù)操作

    使用mysql記錄從url返回的http GET請求數(shù)據(jù)操作

    這篇文章主要介紹了使用mysql記錄從url返回的http GET請求數(shù)據(jù)操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-01-01
  • 對比分析MySQL語句中的IN 和Exists

    對比分析MySQL語句中的IN 和Exists

    mysql中in 是把外表和內(nèi)表作hash 連接,而exists是對外表作loop循環(huán),每次loop循環(huán)再對內(nèi)表進(jìn)行查詢。一直以來認(rèn)為exists比in效率高的說法是不準(zhǔn)確的。
    2018-06-06
  • 分享MYSQL插入數(shù)據(jù)時忽略重復(fù)數(shù)據(jù)的方法

    分享MYSQL插入數(shù)據(jù)時忽略重復(fù)數(shù)據(jù)的方法

    當(dāng)程序中insert時,已存在的數(shù)據(jù)不插入,不存在的數(shù)據(jù)insert。在網(wǎng)上搜了下,可以使用存儲過程或者是用NOT EXISTS 來判斷是否存在
    2013-09-09
  • mysql 基礎(chǔ)教程之庫與表的詳解

    mysql 基礎(chǔ)教程之庫與表的詳解

    這篇文章主要介紹了mysql 基礎(chǔ)教程之庫與表的詳解的相關(guān)資料,需要的朋友可以參考下
    2017-01-01

最新評論