日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql 回滚段_史上最牛分析MySQL索引机制的实现!不接受反驳

發布時間:2024/1/23 数据库 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql 回滚段_史上最牛分析MySQL索引机制的实现!不接受反驳 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

數據庫是一個只要從事后端開發,就永遠離不開的技術,大部分企業選擇的數據庫都是MySQL,所以需要我們對MySQL有著足夠的了解。

而MySQL索引,我們都知道提高性能要加索引,也知道索引的結構是B-Tree,也都可以說出幾條加索引的原則,但再深入一點,往往就會詞窮,這可能就是知其然而不知其所以然的結果了。這會讓我們在實際的開發中,涉及到究竟要給哪個字段加索引,就“拄杖落手心茫然”了。

于是我就問了自己這樣幾個問題,索引究竟是什么呢?索引是存在哪里的呢?MySQL是怎樣通過索引,就優化了性能呢?

本文的研究對象是InnoDB存儲引擎,其他存儲引擎并沒有涉及。

首先想要了解索引究竟存在哪里,如何發揮作用,就不能只研究索引,要結合整個數據庫的存儲結構,運行流程,來分析索引是如何優化查詢過程的。

【一】MySQL的邏輯存儲結構

  • 表空間(tablespace):可以默認為存儲引擎邏輯結構的最高層,存放所有的數據。
  • 段(segment):包括數據段、索引段、回滾段,對于段的管理,由存儲引擎自身完成。
  • 區(extent):1MB,一個區64個頁,InnoDB一次從磁盤申請4~5個區,一個區中有連續的64個頁。
  • 頁(page)/塊(block):每個頁固定大小16KB。
  • 行(row):有Compact和Redundant兩種行存儲格式。

關于一個頁的具體組成,可以從下圖中有一個更直觀的認識:

各個數據頁之間通過雙向鏈表連接,每個頁內各條行記錄用單鏈表連接。

如果沒有任何索引優化,在查詢數據時只能先遍歷雙向鏈表找到對應的頁,加了索引,就可以通過索引的B+樹結構定位對應的頁。

【二】實驗MySQL的數據存儲

為了有更清晰的認識,我們在數據庫中做一個實驗,

在數據庫創建member表,結構如下

DROP TABLE IF EXISTS `member`;CREATE TABLE `member` ( `id` int(10) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, `sex` smallint(2) DEFAULT NULL, `desc` text, PRIMARY KEY (`id`), UNIQUE KEY(`id`,`NAME`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;

創建表后,member.ibd大小是112KB,可見有7個頁,然后用《MySQL技術內幕-InnoDB存儲引擎》中提到的python小工具,查看表空間中各個頁的信息,其中有offset為3和4的兩個數據頁,此時還沒有索引節點。

中間出現的小插曲,導入下面的數據,發現頁信息是這樣的,:

INSERT INTO `member` SELECT '1', '李白', '1', REPEAT('且放白鹿青崖間',500);INSERT INTO `member` SELECT '2', '蘇軾', '1', REPEAT('暮云收盡溢清寒',500);INSERT INTO `member` SELECT '3', '白居易', '1',REPEAT('我寄人間雪滿頭',500);INSERT INTO `member` SELECT '4', '姜夔', '1',REPEAT('淮南皓月冷千山',500);

出現這種情況是因為,當行記錄的長度超過行記錄最大長度時,變長列(variable-length column)會選擇外部溢出頁(overflow page,一般是Uncompressed BLOB Page)進行存儲,于是調整desc列的長度:

INSERT INTO `member` SELECT '1', '李白', '1', REPEAT('且放白鹿青崖間',300);INSERT INTO `member` SELECT '2', '蘇軾', '1', REPEAT('暮云收盡溢清寒',300);INSERT INTO `member` SELECT '3', '白居易', '1',REPEAT('我寄人間雪滿頭'300);INSERT INTO `member` SELECT '4', '姜夔', '1',REPEAT('淮南皓月冷千山',300);

我們知道,InnoDB中,表是根據主鍵順序存儲的(索引組織表),

上圖是page offset為3的數據構成,藍框的部分是File Header和Page Header,紅框的部分是Infimum Records,后面是Supremum Records。

通過Infimum Records可以找到主鍵為1的鍵值,就是綠框的部分,后面的值00 00 00 05就是數據頁頁號,再后面分別是主鍵為2和4對應的Pointer。

【三】聚集索引

InnoDB存儲引擎中,表是索引組織表,所以準確來講,聚集索引不是一種索引類型,而是一種InnoDB中數據的存儲方式,在這種存儲結構中,同時保存了索引和數據行。

簡要聚集索引特點:

  • 按照主鍵構建B+樹
  • 葉子節點就是數據頁(存了該行記錄的所有數據)
  • 一張表只能有一個聚集索引
  • 【四】索引的使用

    • 不同應用中有區別:
  • 因為涉及多表連接,所以建索引是有意義的
  • 通常對時間字段建索引,因為需要按時間維度篩選數據
  • OLTP:只需通過索引獲取表中少部分數據,建索引才有意義
  • OLAP:
    • 聯合索引
  • 聯合索引的第一列可以直接使用這棵B+樹
  • 對于“where col1=? order by col2 ” 的查詢可以直接使用這棵B+樹,因為已經對col2做了排序處理
  • 本質是鍵值數量大于等于2的B+樹
  • 優點:
    • 覆蓋索引
  • 直接從輔助索引查詢,不需查詢聚集索引
  • 輔助索引:鍵+聚集索引鍵,通俗解釋,會根據該索引列建一棵B+樹,鍵是鍵索引的列,但值指向該條記錄對應的聚集索引的頁,
  • 覆蓋索引:查找該條記錄時,不用從頭遍歷聚集索引這棵B+樹,可以從輔助索引這棵B+樹,直接跳到聚集索引那棵B+樹的中間
  • 由于輔助索引不會存儲整行數據的信息,所以大小遠遠小于聚集索引,所以減少了大量的IO操作
    • 一些老生常談的索引使用建議,在日常使用時,要知其然并知其所以然,才能將索引用好
  • 一般為where和join中用到的列建立索引
  • B-Tree索引生效的場景:,>=,BETWEEN,IN,以及不以通配符開始的like
  • 索引字段盡量是簡單數據類型
  • 盡量不要讓索引值默認為NULL
  • 遵守“最左前綴”原則
  • order by也要遵守“最左前綴”原則
  • 【五】幾種類型索引的常用操作:

    • 普通索引
    # 創建索引CREATE INDEX idx_name ON member(name)# 修改表結構ALTER TABLE member ADD INDEX idx_name (name)#創建表直接指定CREATE TABLE mytable( id INT NOT NULL, username VARCHAR(16) NOT NULL, INDEX idx_name (username(2)) )# 刪除索引DROP INDEX idx_name ON member;
    • 唯一索引:唯一索引與普通索引的不同點在于,普通索引列允許重復值,唯一索引列值必須唯一,但允許NULL值。
    # 創建索引CREATE UNIQUE INDEX idx_name ON member(name)# 修改表結構ALTER TABLE member ADD UNIQUE INDEX idx_name (name)#創建表直接指定CREATE TABLE mytable( id INT NOT NULL, username VARCHAR(16) NOT NULL, UNIQUE INDEX idx_name (username(2)) )
    • 主鍵索引:是特殊的唯一索引,不允許NULL值,一個表中只有一個。
    # 一般在建表時指定CREATE TABLE mytable( id INT NOT NULL, username VARCHAR(16) NOT NULL,PRIMARY KEY(id))
    • 組合索引
    ALTER TABLE member ADD INDEX idx_name_sex_desc (name,sex,`desc`(10));

    總結

    以上是生活随笔為你收集整理的mysql 回滚段_史上最牛分析MySQL索引机制的实现!不接受反驳的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。