MySQL數據庫進階第二篇(索引,SQL性能分析,使用規則)

文章目錄

  • 一、索引概述
  • 二、索引結構
  • 三、結構 - B-Tree
  • 四、結構 - B+Tree
  • 五、結構 - Hash
  • 六、索引分類
  • 七、索引語法
    • 1.案例代碼
  • 八、SQL性能分析
    • 1.查看SQl執行頻率
    • 2.慢查詢日志
    • 3.PROFILES詳情
    • 4.EXPLAIN執行計劃
  • 九、 索引使用規則
  • 十、SQL 提示
  • 十一、覆蓋索引
  • 十二、前綴索引
  • 十三、單列索引&聯合索引
  • 十四、索引設計原則

本篇博客深入詳細地介紹了數據庫索引的概念和重要性。內容包含:索引的概念和目標、索引的優點與缺點。此外,博客還深入解析了三種主要的索引結構:B-Tree、B+Tree和Hash,提供了詳細的結構解析和優化方法,并通過插圖進一步增強了理解。
博客的部分內容專注于對B-Tree和B+Tree的對比,以及MySQL中索引結構的原理和實際應用。對索引結構的一些微妙差異,如MySQL在B+Tree基礎上增加指向相鄰葉子節點的鏈表指針,也進行了深入的探討。
在對索引結構進行詳細解析后,博客介紹了幾種不同類型的索引(包括聚簇索引和非聚簇索引)及其適用場景。接著,博客介紹了索引語法,SQL性能分析以及索引直接和索引建議。
總的來說,這篇博客提供了一份詳盡且全面的索引教程和指南,從基本概念到實踐應用,有很高的參考價值。

一、索引概述

索引是幫助 MySQL 高效獲取數據的數據結構(有序)。在數據之外,數據庫系統還維護著滿足特定查找算法的數據結構,這些數據結構以某種方式引用(指向)數據,這樣就可以在這些數據結構上實現高級查詢算法,這種數據結構就是索引。

優點:

提高數據檢索效率,降低數據庫的IO成本
通過索引列對數據進行排序,降低數據排序的成本,降低CPU的消耗
在這里插入圖片描述

缺點:

索引列也是要占用空間的
索引大大提高了查詢效率,但降低了更新的速度,比如 INSERT、UPDATE、DELETE

二、索引結構

在這里插入圖片描述
在這里插入圖片描述

三、結構 - B-Tree

B-Tree (多路平衡查找樹) 以一棵最大度數(max-degree,指一個節點的子節點個數)為5(5階)的 b-tree 為例(每個節點最多存儲4個key,5個指針)

B-Tree結構

在這里插入圖片描述

演示地址:https://www.cs.usfca.edu/~galles/visualization/BTree.html

四、結構 - B+Tree

在這里插入圖片描述
演示地址:https://www.cs.usfca.edu/~galles/visualization/BPlusTree.html

與 B-Tree 的區別:
所有的數據都會出現在葉子節點,葉子節點形成一個單向鏈表

MySQL 索引數據結構對經典的 B+Tree 進行了優化。在原 B+Tree 的基礎上,增加一個指向相鄰葉子節點的鏈表指針,就形成了帶有順序指針的 B+Tree,提高區間訪問的性能。
在這里插入圖片描述

五、結構 - Hash

哈希索引就是采用一定的hash算法,將鍵值換算成新的hash值,映射到對應的槽位上,然后存儲在hash表中。
如果兩個(或多個)鍵值,映射到一個相同的槽位上,他們就產生了hash沖突(也稱為hash碰撞),可以通過鏈表來解決。

Hash索引原理圖

特點:
Hash索引只能用于對等比較(=、in),不支持范圍查詢(betwwn、>、<、…)
無法利用索引完成排序操作
查詢效率高,通常只需要一次檢索就可以了,效率通常要高于 B+Tree 索引

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

面試題
為什么 InnoDB 存儲引擎選擇使用 B+Tree 索引結構?
相對于二叉樹,層級更少,搜索效率高
對于 B-Tree,無論是葉子節點還是非葉子節點,都會保存數據,這樣導致一頁中存儲的鍵值減少,指針也跟著減少,要同樣保存大量數據,只能增加樹的高度,導致性能降低
相對于 Hash 索引,B+Tree 支持范圍匹配及排序操作

六、索引分類

在這里插入圖片描述
在這里插入圖片描述

演示圖:
在這里插入圖片描述
在這里插入圖片描述
聚集索引選取規則:

如果存在主鍵,主鍵索引就是聚集索引
如果不存在主鍵,將使用第一個唯一(UNIQUE)索引作為聚集索引
如果表沒有主鍵或沒有合適的唯一索引,則 InnoDB 會自動生成一個 rowid 作為隱藏的聚集索引

思考題

  1. 以下 SQL 語句,哪個執行效率高?為什么?

select * from user where id = 10;
select * from user where name = ‘Arm’;
– 備注:id為主鍵,name字段創建的有索引
答:第一條語句,因為第二條需要回表查詢,相當于兩個步驟。

  1. InnoDB 主鍵索引的 B+Tree 高度為多少?

答:假設一行數據大小為1k,一頁中可以存儲16行這樣的數據。InnoDB 的指針占用6個字節的空間,主鍵假設為bigint,占用字節數為8.
可得公式:n * 8 + (n + 1) * 6 = 16 * 1024,其中 8 表示 bigint 占用的字節數,n 表示當前節點存儲的key的數量,(n + 1) 表示指針數量(比key多一個)。算出n約為1170。

如果樹的高度為2,那么他能存儲的數據量大概為:1171 * 16 = 18736;
如果樹的高度為3,那么他能存儲的數據量大概為:1171 * 1171 * 16 = 21939856。

另外,如果有成千上萬的數據,那么就要考慮分表,涉及運維篇知識。

七、索引語法

在這里插入圖片描述
創建索引:
CREATE [ UNIQUE | FULLTEXT ] INDEX index_name ON table_name (index_col_name, …);
如果不加 CREATE 后面不加索引類型參數,則創建的是常規索引

查看索引:
SHOW INDEX FROM table_name;

刪除索引:
DROP INDEX index_name ON table_name;

1.案例代碼

在這里插入圖片描述

代碼如下(示例):

-- name字段為姓名字段,該字段的值可能會重復,為該字段創建索引
create index idx_user_name on tb_user(name);
-- phone手機號字段的值非空,且唯一,為該字段創建唯一索引
create unique index idx_user_phone on tb_user (phone);
-- 為profession, age, status創建聯合索引
create index idx_user_pro_age_stat on tb_user(profession, age, status);
-- 為email建立合適的索引來提升查詢效率
create index idx_user_email on tb_user(email);
-- 刪除索引
drop index idx_user_email on tb_user;

八、SQL性能分析

1.查看SQl執行頻率

在這里插入圖片描述
SHOW GLOBAL STATUS LIKE ‘COM_____’

2.慢查詢日志

在這里插入圖片描述

3.PROFILES詳情

在這里插入圖片描述
SHOW PROFILES

4.EXPLAIN執行計劃

在這里插入圖片描述
在這里插入圖片描述

在這里插入圖片描述

九、 索引使用規則

1.最左前綴法則
如果索引關聯了多列(聯合索引),要遵守最左前綴法則,最左前綴法則指的是查詢從索引的最左列開始,并且不跳過索引中的列。
如果跳躍某一列,索引將部分失效(后面的字段索引失效)。

2.聯合索引中,出現范圍查詢(<, >),范圍查詢右側的列索引失效。可以用>=或者<=來規避索引失效問題。

3.在索引列上進行運算操作,索引將失效。如:explain select * from tb_user where substring(phone, 10, 2) = ‘15’;

4.字符串類型字段使用時,不加引號,索引將失效。如:explain select * from tb_user where phone = 17799990015;,此處phone的值沒有加引號

5.模糊查詢中,如果僅僅是尾部模糊匹配,索引不會是失效;如果是頭部模糊匹配,索引失效。如:explain select * from tb_user where profession like ‘%工程’;,前后都有 % 也會失效。

6.用 or 分割開的條件,如果 or 其中一個條件的列沒有索引,那么涉及的索引都不會被用到。

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

十、SQL 提示

是優化數據庫的一個重要手段,簡單來說,就是在SQL語句中加入一些人為的提示來達到優化操作的目的。

例如,使用索引:
explain select * from tb_user use index(idx_user_pro) where profession=“軟件工程”;
不使用哪個索引:
explain select * from tb_user ignore index(idx_user_pro) where profession=“軟件工程”;
必須使用哪個索引:
explain select * from tb_user force index(idx_user_pro) where profession=“軟件工程”;

use 是建議,實際使用哪個索引 MySQL 還會自己權衡運行速度去更改,force就是無論如何都強制使用該索引。

十一、覆蓋索引

在這里插入圖片描述
盡量使用覆蓋索引(查詢使用了索引,并且需要返回的列,在該索引中已經全部能找到),減少 select *。

explain 中 extra 字段含義:
using index condition:查找使用了索引,但是需要回表查詢數據
using where; using index;:查找使用了索引,但是需要的數據都在索引列中能找到,所以不需要回表查詢

如果在聚集索引中直接能找到對應的行,則直接返回行數據,只需要一次查詢,哪怕是select *;如果在輔助索引中找聚集索引,如select id, name from xxx where name=‘xxx’;,也只需要通過輔助索引(name)查找到對應的id,返回name和name索引對應的id即可,只需要一次查詢;如果是通過輔助索引查找其他字段,則需要回表查詢,如select id, name, gender from xxx where name=‘xxx’;
在這里插入圖片描述

所以盡量不要用select *,容易出現回表查詢,降低效率,除非有聯合索引包含了所有字段

面試題:一張表,有四個字段(id, username, password, status),由于數據量大,需要對以下SQL語句進行優化,該如何進行才是最優方案:
select id, username, password from tb_user where username=‘itcast’;

解:給username和password字段建立聯合索引,則不需要回表查詢,直接覆蓋索引

十二、前綴索引

當字段類型為字符串(varchar, text等)時,有時候需要索引很長的字符串,這會讓索引變得很大,查詢時,浪費大量的磁盤IO,影響查詢效率,此時可以只降字符串的一部分前綴,建立索引,這樣可以大大節約索引空間,從而提高索引效率。

語法:create index idx_xxxx on table_name(columnn(n));
前綴長度:可以根據索引的選擇性來決定,而選擇性是指不重復的索引值(基數)和數據表的記錄總數的比值,索引選擇性越高則查詢效率越高,唯一索引的選擇性是1,這是最好的索引選擇性,性能也是最好的。
求選擇性公式:

select count(distinct email) / count() from tb_user;
select count(distinct substring(email, 1, 5)) / count(
) from tb_user;
show index 里面的sub_part可以看到接取的長度
在這里插入圖片描述

十三、單列索引&聯合索引

單列索引:即一個索引只包含單個列
聯合索引:即一個索引包含了多個列
在業務場景中,如果存在多個查詢條件,考慮針對于查詢字段建立索引時,建議建立聯合索引,而非單列索引。

單列索引情況:
explain select id, phone, name from tb_user where phone = ‘17799990010’ and name = ‘韓信’;
這句只會用到phone索引字段

注意事項
多條件聯合查詢時,MySQL優化器會評估哪個字段的索引效率更高,會選擇該索引完成本次查詢
在這里插入圖片描述

十四、索引設計原則

在這里插入圖片描述

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

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

相關文章

滾動加載react-infinite-scroll-component

react-infinite-scroll-component 當請求數據量過大時&#xff0c;接口返回數據時間會很長&#xff0c;數據回顯時間長&#xff0c;Dom 的渲染會有很大的性能壓力。 antd的List組件中有提到一個滾動加載的組件庫react-infinite-scroll-component 實現滾動加載 Antd&#xff1…

考研高數(高階導數的計算)

1.歸納法 常見高階導數 2.泰勒展開式 3.萊布尼茲公式 4.用導數定義證明導函數在某一點連續的例題

【kubernetes】二進制部署k8s集群之cni網絡插件flannel和calico工作原理(中)

↑↑↑↑接上一篇繼續部署↑↑↑↑ 目錄 一、k8s集群的三種接口 二、k8s的三種網絡模式 1、pod內容器之間的通信 2、同一個node節點中pod之間通信 3、不同的node節點的pod之間通信 Overlay Network VXLAN 三、flannel網絡插件 1、flannel插件模式之UDP模式&#xff0…

java對象所占內存大小輸出

如何計算java對象所占內存大小&#xff0c;可以使用下述三種方法。 使用jdk8自帶API 使用下面語句打印對象所占內存大小&#xff1a;需要保證jdk版本是jdk8。System.out.println(ObjectSizeCalculator.getObjectSize(3L)); 借助org.apache.lucene工具類 引入maven坐標 <…

2024/2/22

P8680 [藍橋杯 2019 省 B] 特別數的和 題目描述 小明對數位中含有 2、0、1、9 的數字很感興趣&#xff08;不包括前導 00&#xff09;&#xff0c;在 1 到 40 中這樣的數包括 1、2、9、10 至 32、39 和 40&#xff0c;共28 個&#xff0c;他們的和是574。 請問&#xff0c;在…

【2024軟件測試面試必會技能】

Unittest(5)&#xff1a;unittest_忽略用例 忽略用例 在執行測試腳本的時候&#xff0c;可能會有某幾條用例本次不想執行&#xff0c;但又不想刪也 不想注釋&#xff0c;unittest通過忽略部分測試用例不執行的方式&#xff0c;分無條件忽略和有條 件忽略,通過裝飾器實現所描述…

Vue3+vite搭建基礎架構(11)--- 菜單欄功能和Tab頁功能實現

Vue3vite搭建基礎架構&#xff08;11&#xff09;--- 菜單欄功能和Tab頁功能實現 說明刪除項目中不需要的文件userStore全局屬性代碼菜單欄代碼Tab頁代碼解決瀏覽器輸入地址時不會打開tab頁問題和切換tab頁時參數丟失問題 說明 這里記錄下自己在Vue3vite的項目使用less來寫樣式…

低代碼開發——企業轉型的萬金油

在數字化時代&#xff0c;企業面臨著日新月異的市場環境和激烈的競爭壓力。為了在這場變革中脫穎而出&#xff0c;企業需要不斷優化業務流程、提升創新能力&#xff0c;以及實現敏捷響應。在這個過程中&#xff0c;低代碼開發作為一種創新性的技術手段&#xff0c;正成為企業轉…

統信UOS_麒麟KYLINOS上監控網絡:探索Smokeping的強大功能

原文鏈接&#xff1a;統信UOS|麒麟KYLINOS上監控網絡&#xff1a;探索Smokeping的強大功能 在當今的網絡環境中&#xff0c;無論是個人用戶還是企業用戶&#xff0c;都非常重視網絡的穩定性和連通性。特別是在進行遠程工作、在線會議、云計算等活動時&#xff0c;網絡質量直接影…

程序員必備技能----刪庫跑路大總結

刪庫跑路大總結&#xff0c;各個都是大殺器&#xff0c;破壞性太大&#xff0c;輕易不要嘗試。 刪除linux根目錄&#xff0c;用戶目錄&#xff0c;其實還可以增加一個刪除/etc。刪除&#xff08;清除&#xff09;數據庫。刪除redis緩存和持久化文件。刪除mongodb庫。git push …

說一說Eclipse的項目類型和常用項目的區別

Eclipse在新建項目的時候有很多類型&#xff0c;包括Java project、Web project等等&#xff0c;如下&#xff1a; 那么這些項目類型有什么區別呢&#xff1f;我們在創建項目的時候應該如何選擇&#xff0c;了解清楚這一點還是非常重要的&#xff0c;但記住一個出發點&#xff…

2.22 day3、4 QT

完善對話框&#xff0c;點擊登錄對話框&#xff0c;如果賬號和密碼匹配&#xff0c;則彈出信息對話框&#xff0c;給出提示"登錄成功”&#xff0c;提供一個Ok按鈕&#xff0c;用戶點擊Ok后&#xff0c;關閉登錄界面&#xff0c;跳轉到其他界面 如果賬號和密碼不匹配&…

讀書筆記:《看電影學金融》

大空頭 禁止做空可以延緩資產價格下降的過程&#xff0c;但是人為保護的高股價最終還是不能持續的。做空引入的空頭買家&#xff0c;可以增加市場的流動性。住房價格指數期貨使房地產的投資屬性與住宅屬性分離&#xff0c;降低因炒房而空置的房屋&#xff0c;降低房價。收益互…

【論文解讀】Uncertainty Quantification of Collaborative Detection for Self-Driving

Uncertainty Quantification of Collaborative Detection for Self-Driving 摘要引言方法問題定義方法概覽Double-M 實驗結論 摘要 在聯網和自動駕駛汽車(CAVs)之間共享信息從根本上提高了自動駕駛協同目標檢測的性能。然而&#xff0c;由于實際挑戰&#xff0c;CAV 在目標檢測…

十九、圖像的放縮和插值

項目功能實現&#xff1a;對一張圖像進行放大和縮小操作 按照之前的博文結構來&#xff0c;這里就不在贅述了 一、頭文件 resizing.h #pragma once#include<opencv2/opencv.hpp>using namespace cv;class RESIZING { public:void resizing(Mat& image); };#pragma…

深度解析:用 Python 爬蟲逆向破解 dappradar 的請求頭加密 X-Api-Sk

大家好!我是愛摸魚的小鴻,關注我,收看每期的編程干貨。 逆向是爬蟲工程師進階必備技能,當我們遇到一個問題時可能會有多種解決途徑,而如何做出最高效的抉擇又需要經驗的積累。本期文章將以實戰的方式,帶你詳細地逆向分析 dappradar 網站請求頭加密字段 X-Api-SK 的構造邏…

解決Edge瀏覽器,微博無法查看大圖(Edge Image Viewer)

使用Edge瀏覽器瀏覽微博或其它帶校驗的圖片時&#xff0c;會導致無法查看。 主要原因為Edge自帶了一個Edge Image Viewer, 但是該圖片查看器無法查看帶校驗數據的圖片&#xff0c;所以導致查看時一片空白。 解決方法 地址欄輸入 edge://flags/搜索 Edge Image Viewer選擇 Disa…

HTML5 Canvas 限定文本區域大小,文字自動換行,自動縮放

<!DOCTYPE html> <html> <body><h1>HTML5 Canvas 限定文本展示范圍、自動計算縮放字體大小</h1><div id"tips">0</div> <div id"content">良田千頃不過一日三餐廣廈萬間只睡臥榻三尺良田千頃不過一日三餐…

【Day53】代碼隨想錄之動態規劃_買賣股票ⅠⅡ

文章目錄 動態規劃理論基礎動規五部曲&#xff1a;出現結果不正確&#xff1a; 1. 買賣股票的最佳時機2. 買賣股票的最佳時機Ⅱ 動態規劃理論基礎 動規五部曲&#xff1a; 確定dp數組 下標及dp[i] 的含義。遞推公式&#xff1a;比如斐波那契數列 dp[i] dp[i-1] dp[i-2]。初…