MySQL索引、B+樹相關知識匯總
- 一、有一個查詢需求,MySQL中有兩個表,一個表1000W數據,另一個表只有幾千數據,要做一個關聯查詢,如何優化?
- 1、為關聯字段建立索引
- 2、小表驅動大表
- 二、b樹和b+樹的區別
- 1、更高的查詢效率
- 2、更高的空間利用率
- 3、查詢效率更穩定
- 三、innodb使用數據頁存儲數據?默認數據頁大小16K,我現在有一張表,有2kw數據,我這個b+樹的高度有幾層?
- 四、redis為什么快?
- 1、基于內存的數據存儲
- 2、單線程模型
- 3、IO多路復用
- 4、高效的數據結構
- 五、建立聯合索引(a,b,c),where c = 5是否會用到索引?為什么?
一、有一個查詢需求,MySQL中有兩個表,一個表1000W數據,另一個表只有幾千數據,要做一個關聯查詢,如何優化?
如果 orders 表是大表(比如 1000 萬條記錄),而 users 表是相對較小的表(比如幾千條記錄)。
1、為關聯字段建立索引
確保兩個表中用于 JOIN 操作的字段都有索引。這是最基本的優化策略,避免數據庫進行全表掃描,可以大幅度減少查找匹配行的時間。
2、小表驅動大表
在執行 JOIN 操作時,先過濾小表中的數據,這樣可以減少后續與大表進行 JOIN 時需要處理的數據量,從而提高查詢效率。
二、b樹和b+樹的區別
B+ 樹相比較 B 樹,有這些優勢:
1、更高的查詢效率
B+樹的所有值(數據記錄或指向數據記錄的指針)都存在于葉子節點,并且葉子節點之間通過指針連接,形成一個有序鏈表。
這種結構使得 B+樹非常適合進行范圍查詢,一旦到達了范圍的開始位置,接下來的元素可以通過遍歷葉子節點的鏈表順序訪問,而不需要回到樹的上層。如 SQL 中的 ORDER BY 和 BETWEEN 查詢。
而 B 樹的數據分布在整個樹中,進行范圍查詢時可能需要遍歷樹的多個層級。
2、更高的空間利用率
在 B+樹中,非葉子節點不存儲數據,只存儲鍵值,這意味著非葉子節點可以擁有更多的鍵,從而有更多的分叉。
這導致樹的高度更低,進一步降低了查詢時磁盤 I/O 的次數,因為每一次從一個節點到另一個節點的跳轉都可能涉及到磁盤 I/O 操作。
3、查詢效率更穩定
B+樹中所有葉子節點深度相同,所有數據查詢路徑長度相等,保證了每次搜索的性能穩定性。而在 B 樹中,數據可以存儲在內部節點,不同的查詢可能需要不同深度的搜索。
三、innodb使用數據頁存儲數據?默認數據頁大小16K,我現在有一張表,有2kw數據,我這個b+樹的高度有幾層?
在 MySQL 中,InnoDB 存儲引擎的最小存儲單元是頁,默認大小是16k
如果有 2KW 條數據,那么這顆 B+樹的高度為 3 層。
四、redis為什么快?
1、基于內存的數據存儲
Redis 將數據存儲在內存當中,使得數據的讀寫操作避開了磁盤 I/O。而內存的訪問速度遠超硬盤,這是 Redis 讀寫速度快的根本原因。
2、單線程模型
Redis 使用單線程模型來處理客戶端的請求,這意味著在任何時刻只有一個命令在執行。這樣就避免了線程切換和鎖競爭帶來的消耗。
3、IO多路復用
Redis 單個線程處理多個 IO 讀寫的請求。
4、高效的數據結構
Redis 提供了多種高效的數據結構,如字符串(String)、列表(List)、集合(Set)、有序集合(Sorted Set)等,這些數據結構經過了高度優化,能夠支持快速的數據操作。
五、建立聯合索引(a,b,c),where c = 5是否會用到索引?為什么?
在這個查詢中,只有索引的第三列 c 被用作查詢條件,而前兩列 a 和 b 沒有被使用。這不符合最左前綴原則,因此 MySQL 不會使用聯合索引 (a,b,c)。
1、對empname,deptid,jobs3列建立索引語句:
create index idx_t1_bcd on employees(empname,deptid,jobs)
2、EXPLAIN select * from employees where jobs=“測試經理” ,沒有使用索引
3、EXPLAIN select * from employees where deptid=“1003” ,沒有使用索引
4、EXPLAIN select * from employees where empname=“張飛” 使用了索引
5、EXPLAIN select * from employees where jobs=“測試” and deptid=“1002”
沒有使用索引
6、EXPLAIN select * from employees where jobs=“測試” or deptid=“1002”
沒有使用索引
7、EXPLAIN select * from employees where deptid=“1002” and jobs=“測試” and empname=“張飛” 使用了索引
8、EXPLAIN select * from employees where deptid=“1002” or jobs=“測試” or empname=“張飛” 不使用索引
9、EXPLAIN select * from employees where deptid=“1002” and jobs=“測試” and empname LIKE “%飛”;不使用索引
10、EXPLAIN select * from employees where deptid LIKE “%002” and jobs=“測試” and empname = “張飛”;使用了索引