【Java面試】四、MySQL篇(上)

在這里插入圖片描述

文章目錄

  • 1、定位慢查詢
  • 2、慢查詢的原因分析
  • 3、索引
    • 3.1 數據結構選用:二叉樹 & 紅黑樹
    • 3.2 數據結構選用:B+樹
  • 4、聚簇索引、非聚簇索引、回表查詢
    • 4.1 聚簇索引、非聚簇索引
    • 4.2 回表查詢
  • 5、覆蓋索引、超大分頁優化
    • 5.1 覆蓋索引
    • 5.2 超大分頁處理
  • 6、索引的創建
  • 7、索引的失效
  • 8、SQL優化的經驗
  • 9、面試

1、定位慢查詢

  • Arthas在線查看方法耗時
  • 運維工具Prometheus
  • 鏈路追蹤工具Skywalking、Zipkin、OpenTemplate

在這里插入圖片描述

  • MySQL自帶的慢日志:記錄執行超過n秒的SQL
//修改配置文件,文件位置
/etc/my.cnf//開啟慢查詢開關,生產環境不建議開啟,會損失部分性能
slow_query_log=1//設置超過2秒的SQL
long_query_time=2

慢SQL被記錄到/var/lib/mysql/localhost-slow.log

在這里插入圖片描述

2、慢查詢的原因分析

慢SQL通常是因為:

  • 聚合查詢
  • 多表查詢
  • 表數據量過大查詢
  • 深度分頁查詢

前三種,可嘗試使用SQL執行計劃分析原因:

# SELECT語句前添加EXPLAIN或DESC,查看SQL語句執行情況的信息
EXPLAIN select * from t_table;
DESC select * from t_table;

在這里插入圖片描述
此時SELECT返回的不是表數據,是一些執行信息:

  • possible: key 當前sql可能會使用到的索引
  • key: 當前sql實際命中的索引
  • key_len: 索引占用的大小,key和key_len搭配,檢查是否存在索引失效
  • Extra:額外的優化建議

在這里插入圖片描述

  • type:這條sql的連接的類型,性能由好到差為NULL、system、const、eq_ref、ref、range、index、all
system:查詢MySQL系統內置庫的表const:根據主鍵查詢eq_re:主鍵索引查詢或唯一索引查詢ref:索引查詢range:范圍查詢index:索引樹掃描,遍歷整個索引all:不走索引,全盤掃描

3、索引

一種用于高效查數據的數據結構,以某種方式指向表里的數據。如下表,不加索引,查age=45的數據,就是逐行對比 + 遍歷整個表直至最后一行,效率低下

在這里插入圖片描述

如果去維護一個類似二叉樹的結構,再查age=45的數據,則直接從根節點開始? 45 > 36,去右側 ? 45 < 48 ?去左側 ? 查找完畢,如此,查找效率提升,這即索引的思想

3.1 數據結構選用:二叉樹 & 紅黑樹

MySQL索引底層的數據結構是B+樹。不選二叉樹是因為:

在這里插入圖片描述
如果數據遞增或遞減,此時二叉樹變鏈表,即最壞情況的二叉樹效率很低。既然二叉樹有平衡性問題,那再考慮自平衡的二叉樹 ? 紅黑樹

在這里插入圖片描述

紅黑樹時間復雜度為O(log n),但其也是一個二叉樹,每個節點最多只能兩個分支,因此,大數據量下,紅黑樹會很高。 ? B樹,每個節點可以多個分支,是一種多叉路衡查找樹。以一顆5階B樹為例(最大度數mas-degree為5,每個節點最多存儲4個key)

在這里插入圖片描述

圖中的灰色部分,存儲指針,指向子節點。如20左側的指針,指向的就是20以內的數據,20和30之間的指針,則指向20~30之間的數據,以此類推。且綠色部分存儲的是對應的那條數據。

3.2 數據結構選用:B+樹

相比二叉樹,B樹是一種矮胖樹,B+樹則是B樹的一種優化,非葉子節點只存儲指針,不存儲數據。只有在葉子節點才去存儲對應的數據,前面的非葉子節點起一個導航的作用,非葉子節點上就匹配到的數據,在葉子節點上也能找到這個數。

在這里插入圖片描述

MySQL默認的存儲引擎InnoDB默認使用B+樹實現索引。相比B樹,B+樹:

  • 磁盤讀寫代價更低(只有葉子節點存數據)
  • 查詢效率更穩定(最后都要落到葉子節點)
  • 適合于區間查詢(葉子節點之間的雙向指針,比如查6~34這個區間的數,先從根節點對比,走左邊,到16,再走左邊,到6,再跟雙向指針拿到6到34的數據,不需要再從根節點開始重新找一次

4、聚簇索引、非聚簇索引、回表查詢

4.1 聚簇索引、非聚簇索引

聚簇索引(又叫聚集索引),即B+樹的葉子節點保存的是整行數據。非聚簇索引(又叫二級索引),即B+樹單獨葉子節點存儲的是那行數據對應的主鍵

在這里插入圖片描述
聚簇索引選取規則:(節點里存哪個)

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

如下:建立聚簇索引時,這張表有主鍵ID,因此,節點中存儲的是ID值,最后,葉子節點中存的那個row是整條數據值。

在這里插入圖片描述

再比如給表的name字段建立非聚簇索引,節點存儲name的值,最后的葉子節點,存儲的是這條數據的主鍵值

4.2 回表查詢

select * form user where name = 'Arm';

給name字段加了非聚簇索引,因此,執行如上SQL,先根據name的非聚簇索引的B+樹 ? A小于L,走左邊,到G和J,再走左邊,找到Arm ? 因為是select *,而非聚簇索引的葉子節點存的是主鍵 ? 拿著主鍵,回到聚簇索引,從其根節點開始查 ? 聚簇索引的葉子節點存了整行數據,返回select * 的結果

在這里插入圖片描述

總之,回表查詢就是:先根據非聚簇索引找到主鍵值,再根據主鍵值到聚簇索引拿到整行數據

5、覆蓋索引、超大分頁優化

5.1 覆蓋索引

即查詢使用了索引,并且你需要返回的字段,在索引中能夠全部找到。

在這里插入圖片描述

select * form tb_user where id = 1;

是覆蓋索引,雖然select * ,但其where是根據id過濾的,即用的是主鍵索引、聚簇索引,索引的葉子節點存了整行數據,需要返回的字段,在索引中能夠全部找到

在這里插入圖片描述

select id, name from tb_user where name = 'Arm';

是覆蓋索引,where根據name過濾,走name的非聚簇索引,最后葉子節點存了id,而最后需要返回的就是id和name

在這里插入圖片描述

select id, name, gender from tb_user where name = 'Arm';

不是覆蓋索引,索引中拿不到gender值,需要回表查詢

在這里插入圖片描述

很明顯,能一次查詢出來的,符合覆蓋索引的,效率最高,走回表查詢的SQL,效率低

5.2 超大分頁處理

使用limit分頁查,需要對數據進行排序,數據量很大時,效率很低

在這里插入圖片描述

比如,limit 900 0000,10,此時,需要排序前9000010行數據,再返回9000000到9000010行這10行:

在這里插入圖片描述

解決方案是:覆蓋索引 + 子查詢

在這里插入圖片描述
即先根據主鍵去分頁order by id ,不select *,而是select id,再和原來的表關聯查

6、索引的創建

需要創建索引的場景:

  • 數據量大(單表超過10萬行),且查詢頻繁
  • 給常作為where、order by、group by操作的字段創建索引
  • 如果字段是字符串類型,且長度很長,給其建立索引壓力大,可截取前幾個字,建立前綴索引

在這里插入圖片描述

  • 多用聯合索引,而不是單列索引。因為如果給A + B兩個字段建立了聯合索引,剛好又select A, B from table where A = 1;就是覆蓋索引,避免了回表,查詢效率更高。下圖即給name、status、address三個字段建了聯合索引

在這里插入圖片描述

  • 索引并不是越多越好,因為增刪改也要同步去維護索引,索引多了,會影響增刪改的效率

7、索引的失效

給表tb_seller的name,status,address字段創建聯合索引:

在這里插入圖片描述
索引失效的場景:

1)違反最左前綴法則

最左前綴法則,即select后面的字段,必須從索引的最左前列開始,并且不跳過索引中的列。以下為索引不失效的寫法:

在這里插入圖片描述

以下寫法索引失效:
在這里插入圖片描述
以下寫法,中途跳過了聯合索引的某一列,只有最左側字段索引生效,從key_len的大小可以看出,其只命中了一個字段:

在這里插入圖片描述

2)對status范圍查詢,則status右邊的列address沒有用到索引,但name,status還是走了索引了

在這里插入圖片描述

3)在索引所在的列上進行運算,索引會失效

在這里插入圖片描述

4)字符串不加單引號,索引失效

因為不對字符串類型加單引號,MySQL優化器會自動進行類型轉換,造成索引失效
在這里插入圖片描述

5)以%開頭的Like模糊查詢,索引失效

注意:如果僅僅是末尾進行模糊查詢,索引不會失效

在這里插入圖片描述

8、SQL優化的經驗

1)表設計優化:

  • 設置合適的數值類型:tinyint、int、bigint
  • 字符串類型,char和varchar,char定長、效率高,varchar長度靈活可變,根據字符串實際長度來,但效率稍低

在這里插入圖片描述

2)SQL語句優化

  • 避免select *
  • 避免索引失效的寫法
  • 使用union all代替union,union會把兩個查詢的結果再做個去重

在這里插入圖片描述

  • 避免where中對字段進行計算操作
  • join表時,能用inner join,不left join或者right join,業務必須要用時,可將小表(行數少的表)放外面。原因參考for循環嵌套,如下寫法,MySQL進行三次連接,每次連接進行1000次操作,反之就是進行1000次連接,每次連接進行3次操作(inner join 就會自動優化,把小表放外面。left join或right join就不會把小表放外面)

在這里插入圖片描述
3)讀寫分離,主從復制

  • 用于避免寫操作影響查詢效率
  • 主庫寫,從庫讀

在這里插入圖片描述
4)索引的創建和失效
5)分庫分表(見下篇)

9、面試

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

在這里插入圖片描述

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

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

相關文章

聯發科MT8370平臺Genio 510物聯網應用程序處理器詳細規格參數

MT8370是一款高度集成、功能強大的平臺&#xff0c;專為各種人工智能(AI)和物聯網(IoT)用例而設計&#xff0c;這些用例需要高性能邊緣處理、先進的多媒體和連接功能、多個高分辨率攝像頭、連接的觸摸屏顯示器以及多任務高級操作系統(HLOS)的使用。http://Genio 510 (MT8370) E…

Mybatis源碼剖析

文章目錄 一、前置1.1概念ORMSqlSession會話 二、快速入門2.1 SpringBoot整合Mybatis2.2 XML配置2.2.1 路徑位置2.2.2 名稱2.2.3 configuration標簽內容環境environments標簽映射器mappers標簽 2.3 Mapper接口2.3.1 單Mybatis項目2.3.2 SpringBoot整合mybatis2.3.3 m整合mybati…

字符串函數(2)<C語言>

前言 快一周沒更博客了&#xff0c;最近有點忙&#xff0c;今天閑下來了&#xff0c;還是不行&#xff0c;繼續干&#xff0c;書接上回繼續介紹字符串函數&#xff1a;strncpy()、strncat()、strcmp()、strtok()使用、strstr()使用以及模擬實現、strerror()使用。 strncpy()、s…

blender serpens3 個人總結

Serpens 全節點個人備注 快捷鍵 &#xff1a;shift v&#xff1a; 從復制版 添加執行操作&#xff08;blender任何執行動作按鈕&#xff0c;右鍵可以獲取操作命令&#xff09; 概念分析&#xff1a; 屬性&#xff08;Properties&#xff09;&#xff1a;用于定義持久性數據…

揭秘網絡編程:同步與異步IO模型的實戰演練

摘要 ? 在網絡編程領域&#xff0c;同步(Synchronous)、異步(Asynchronous)、阻塞(Blocking)與非阻塞(Non-blocking)IO模型是核心概念。盡管這些概念在多篇文章中被廣泛討論&#xff0c;它們的抽象性使得徹底理解并非易事。本文旨在通過具體的實驗案例&#xff0c;將這些抽象…

在React中使用Sass實現Css樣式管理-10

0. 什么是Sass Sass(Syntactically Awesome Stylesheets)是一個 CSS 預處理器&#xff0c;是 CSS 擴展語言&#xff0c;可以幫助我們減少 CSS 重復的代碼&#xff0c;節省開發時間&#xff1a; Sass 引入合理的樣式復用機制&#xff0c;可以節約很多時間來重復。支持變量和函…

【HM】簡單說明白:裝飾器@State、@Prop、@Link、@Provide、@Consume修飾變量,@Watch監聽變量狀態發生變化

首先要明白什么是“狀態變量”&#xff1f;即被狀態裝飾器&#xff08;State、Prop、Link、Provide、Consume&#xff09;修飾的變量&#xff0c;比如 State str : string; str就是狀態變量。狀態變量值的改變會引起UI界面重新渲染。 State State裝飾的變量&#xff0c;是私…

C++之“流”-第2課-C++和C標準輸入輸出同步

為什么C和C的標準輸入輸出不同步時&#xff0c;數據會混亂&#xff1f;同步會帶來多大性能損失&#xff1f;為什么說這個損失通常不用太在乎&#xff1f; 0. 課堂視頻 C之“流”-第2課&#xff1a;和C輸入輸出的同步 1. 理解cin和cout的類型與創建過程 std::cout 是std::ostre…

Ubuntu系統Discover軟件中心簡介

Discover軟件中心是Ubuntu操作系統中默認的軟件管理工具&#xff0c;它提供了一個圖形用戶界面(GUI)來幫助用戶瀏覽、搜索、安裝和卸載軟件包。Discover軟件中心是Ubuntu軟件中心(Ubuntu Software Center)的繼承者&#xff0c;它在Ubuntu 16.04 LTS版本中首次被引入&#xff0c…

添加、修改和刪除字典元素

自學python如何成為大佬(目錄):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 由于字典是可變序列&#xff0c;所以可以隨時在字典中添加“鍵-值對”。向字典中添加元素的語法格式如下&#xff1a; dictionary[key] value 參數…

You don‘t have enough free space或者no space left on device異常

1.磁盤空間不足 Linux安裝軟件顯示 You dont have enough free space 或者docker拉鏡像時&#xff0c;出現磁盤空間不足的情況 no space left on device 如果你是ubuntu系統。查看磁盤空間 df -h 多半是這個目錄滿了/dev/mapper/ubuntu--vg-ubuntu--lv 大多情況我們只希望擴…

學習編程對英語要求高嗎?

學習編程并不一定需要高深的英語水平。我這里有一套編程入門教程&#xff0c;不僅包含了詳細的視頻講解&#xff0c;項目實戰。如果你渴望學習編程&#xff0c;不妨點個關注&#xff0c;給個評論222&#xff0c;私信22&#xff0c;我在后臺發給你。 雖然一些編程資源和文檔可能…

typora自動生成標題序號(修改V1.0)

目錄 帶序號效果圖 解決方法 帶序號效果圖 解決方法 1.進入文件夾&#xff1a;文件–>偏好設置–>外觀–>主題–>打開主題文件夾 2.如果沒有base.user.css文件&#xff0c;新建一個。如果有直接用記事本打開&#xff0c;把下面代碼拷貝進去保存。 /** initiali…

【JUC編程】-多線程和CompletableFuture的使用

多線程編程 文章目錄 多線程編程[toc]引言創建多線程的方式繼承Thread類實現Runnable接口實現Callable接口Callable和Runnable的區別 Lambda表達式 線程的實現原理Future&FutureTask具體使用submit方法Future到FutureTask類Future注意事項局限性 CompletionService引言使用…

第八大奇跡

目錄 題目描述 輸入描述 輸出描述 輸入輸出樣例 示例 輸入 輸出 運行限制 原題鏈接 代碼思路 題目描述 在一條 R 河流域&#xff0c;繁衍著一個古老的名族 Z。他們世代沿河而居&#xff0c;也在河邊發展出了璀璨的文明。 Z 族在 R 河沿岸修建了很多建筑&#xff0c…

java如何向數組中插入元素

java的數組是不可改變的&#xff0c;因此如果要向數組中插入新的元素&#xff0c;需要新建一個數組&#xff0c;新的數組元素個數減去老數組元素個數的差大于等于要插入新的元素數量。 假如說要插入一個數組元素&#xff0c;需要把新元素插入到中間&#xff0c;把新的數組分為…

Vue組件通訊?組件中通過 provide 來提供變量,然后在?組件中通過 inject 來注?變量例子

在Vue中&#xff0c;provide 和 inject 主要用于依賴注入&#xff0c;允許祖先組件向其所有子孫組件提供一個依賴&#xff0c;而不論組件層次有多深。這在開發高階插件/組件庫時特別有用。 以下是一個簡單的例子&#xff0c;演示了如何在父組件中使用 provide 提供變量&#x…

軟件測試面試題(八)

一&#xff1a;TestDirector有哪些功能&#xff0c;如何對軟件測試過程進行管理&#xff1f; 需求管理 定義測試范圍 定義需求樹 描述需求樹的功能點 測試計劃 定義測試目標和測試策略 分解應用程序&#xff0c;建立測試計劃樹 確定每個功能點的測試方法 將每個功能點連接…

Ps 濾鏡:消失點

Ps菜單&#xff1a;濾鏡/消失點 Filter/Vanishing Point 快捷鍵&#xff1a;Ctrl Alt V 兩條平行的鐵軌或兩排樹木連線相交于很遠很遠的某一點&#xff0c;這點在透視圖中叫做“消失點”&#xff0c;也稱為“滅點”。 消失點 Vanishing Point濾鏡主要用于在圖像中處理具有透視…

C++入門3——類與對象(2)

1.類的6個默認成員函數 如果一個類中什么成員都沒有&#xff0c;簡稱為空類。可是空類中真的什么都沒有嗎&#xff1f; 其實并不是的&#xff0c;任何類在什么都不寫時&#xff0c;編譯器會自動生成以下6個默認成員函數。 默認成員函數&#xff1a;用戶沒有顯式實現&#xf…