面試問我SQL回表?我瞬間蒙了
我們最近在看關于Mysql 的相關知識,也和現在面試的小伙伴們做了一些采訪,問到了一些相關的面試題,說實話,現在面試問的是越來越復雜了,很多時候也不從基礎問了,直接項目走起,然后深挖項目中的一些問題,接著就是數據庫中的相關問題,今天了不起來和大家一起聊一下關于 Mysql 幾個經常問,但是卻讓人很蒙圈的面試題。
索引覆蓋
在面試的時候,面試官很多會提問道優化SQL,至于怎么優化,了不起就不用再繼續贅述這個問題,我們往下延伸,你了解索引覆蓋么?
索引覆蓋(Covering Index)或稱為覆蓋索引,是數據庫中的一種優化手段。
當我們執行一個SQL查詢時,如果只需要查詢某幾個字段的值,并且這幾個字段的數據都已經被包含在某一個索引中(而不是全表掃描),那么數據庫引擎就會直接通過這個索引來取得數據,而無需再回表查詢,從而大大減少了I/O操作,提高了查詢效率。
索引覆蓋的優點就比如有:
- 減少I/O次數:因為通過覆蓋索引可以直接獲取數據,所以不需要再回表查詢,從而減少了I/O次數。
- 提高查詢速度:由于減少了I/O操作,查詢速度自然也得到了提高。
- 索引的選擇性:選擇性是指不重復的索引值與數據表的總記錄數的比值。選擇性越高,通過索引篩選出的數據就越少,從而提高了查詢效率。
這個我們就牽扯到回表查詢了?面試官一般就會套路的繼續往下問,那你知道回表操作么?
SQL回表
那么什么是 SQL 回表呢?
SQL回表,在MySQL數據庫特別是InnoDB存儲引擎中,是一個重要的概念。
SQL回表是指在使用非聚簇索引(也稱為輔助索引或二級索引)進行查詢時,由于非聚簇索引中只存儲了索引字段的值和對應的主鍵(聚簇索引)鍵值,因此,如果需要獲取非索引列的數據,則需要根據主鍵(聚簇索引)中的鍵值去查找實際的數據行。這個過程被稱為“回表”。
回表的原理
- 非聚簇索引結構:非聚簇索引的葉子節點存儲的是(索引列的值,主鍵的值)。
- 查詢過程:當使用非聚簇索引進行查詢時,首先通過非聚簇索引找到滿足條件的主鍵鍵值。然后,根據這些主鍵鍵值,再回到聚簇索引(主鍵索引)中查找完整的數據行。
假設有一個用戶表users,包含id(主鍵)、name和age三個字段,其中在name字段上建立了非聚簇索引。
執行查詢SELECT * FROM users WHERE name='Tom'時,會發生回表。因為首先會通過name上的非聚簇索引找到滿足條件的id,然后再根據這些id回到聚簇索引中查找完整的用戶數據。
而查詢SELECT id, name FROM users WHERE name='Tom'則不會回表,因為所需的數據都在非聚簇索引中可以找到。
而回表操作會增加I/O次數,從而可能影響查詢性能。特別是在大表和復雜查詢場景下,回表操作可能成為性能瓶頸。
為了減少回表操作,可以考慮將需要查詢的字段加入到索引中,形成復合索引(也稱為聯合索引或覆蓋索引)。這樣,查詢時就可以直接從索引中獲取到需要的數據,而無需回表。
所以,建立索引的時候,我們要非常注意,并不是說索引不好,而是說要會加才可以。
索引的最左匹配原則
有的時候,我們建立索引大部分都不會只是單獨的一個字段,所以就有了復合索引。
索引的最左匹配原則(Leftmost Prefix Rule) 主要是在使用復合索引(也稱為多列索引或多字段索引)時的一個關鍵概念。這個原則指出,當使用復合索引進行查詢時,查詢條件應該盡可能地從索引的最左邊開始匹配,這樣索引才能被有效地使用。
當你基于復合索引進行查詢時,查詢條件必須包含索引的最左邊的一列或多列,以便索引能夠被有效地使用。例如,如果你有一個基于(last_name, first_name)的復合索引,以下查詢可以有效地使用這個索引:
查詢基于last_name:SELECT * FROM employees WHERE last_name = 'Smith';
查詢基于last_name和first_name:SELECT * FROM employees WHERE last_name = 'Smith' AND first_name = 'John'; 但是,以下查詢則不能有效地使用這個索引(因為它沒有包含索引的最左邊的列last_name):
查詢僅基于first_name:SELECT * FROM employees WHERE first_name = 'John';
在創建復合索引時,列的順序很重要。你應該將最常用于查詢條件的列放在索引的最左邊。例如,如果你經常基于last_name進行查詢,但很少基于first_name進行查詢,那么你應該創建一個基于(last_name, first_name)的索引,而不是基于(first_name, last_name)的索引。
雖然最左匹配原則是一個重要的概念,但并不意味著你必須始終遵循它。在實際應用中,你需要根據查詢的需求和數據的分布來決定是否使用復合索引以及索引的列順序。
你學會了么?