MySQL 定位用戶記錄的過程可以描述為:打開索引 -> 根據(jù)索引鍵值逐層查找 B+ 樹 branch 結點 -> 定位到葉子結點,將 cursor 定位到滿足條件的 rec 上;如果樹高為 N, 則需要讀取索引樹上的 N 個結點并進行比較,如果 buffer_pool 較小,則大量的操作都會在 pread 上,用戶響應時間變長;另外,MySQL中 Server 層與 Engine 之間的是以 row 為單位進行交互的,engine 將記錄返回給 server 層,server 層對 engine 的行數(shù)據(jù)進行相應的計算,然后緩存或發(fā)送至客戶端,為了減少交互過程所需要的時間,MySQL 做了兩個優(yōu)化:
如果同一個查詢語句連續(xù)取出了 MYSQL_FETCH_CACHE_THRESHOLD(4) 條記錄,則會調用函數(shù) row_sel_enqueue_cache_row_for_mysql 將 MYSQL_FETCH_CACHE_SIZE(8) 記錄緩存至 prebuilt->fetch_cache 中,在隨后的 prebuilt->n_fetch_cached 次交互中,都會從prebuilt->fetch_cache 中直接取數(shù)據(jù)返回到 server 層,那么問題來了,即使是用戶只需要 4 條數(shù)據(jù),Engine 層也會將 MYSQL_FETCH_CACHE_SIZE 條數(shù)據(jù)放入 fetch_cache 中,造成了不必要的緩存使用。另外, 5.7 可以根據(jù)用戶的設置來調整緩存用戶記錄的條數(shù);
Engine 取出數(shù)據(jù)后,會將 cursor 的位置保存起來,當取下一條數(shù)據(jù)時,會嘗試恢復 cursor 的位置,成功則并繼續(xù)取下一條數(shù)據(jù),否則會重新定位 cursor 的位置,從而通過保存 cursor 位置的方法可以減少 server 層 & engine 層交互的時間;
???Server 層 & engine 層交互的過程如下,由于 server & engine 的 row format 不一樣,那么 engine row format -> server row format 在讀場景下的開銷也是比較大的。
while (rc == NESTED_LOOP_OK && join->return_tab >= join_tab) { int error; if (in_first_read) { in_first_read= false; error= (*join_tab->read_first_record)(join_tab); } else error= info->read_record(info); /* load data from engine */ rc= evaluate_join_record(join, join_tab); /* computed by server */ }
AHI 功能作用
????由以上的分析可以看到 MySQL 一次定位 cursor 的過程即是從根結點到葉子結點的路徑,時間復雜度為:height(index) + [CPU cost time],上述的兩個優(yōu)化過程無法省略定位 cursor 的中間結點,因此需要引入一種可以從 search info 定位到葉子結點的方法,從而省略根結點到葉子結點的路徑上所消耗的時間,而這種方法即是 自適應索引(Adaptive hash index, AHI)。查詢語句使用 AHI 的時候有以下優(yōu)點:
- ssh框架 2016-09-30
- 阿里移動安全 [無線安全]玩轉無線電——不安全的藍牙鎖 2017-07-26
- 消息隊列NetMQ 原理分析4-Socket、Session、Option和Pipe 2024-03-26
- Selective Search for Object Recognition 論文筆記【圖片目標分割】 2017-07-26
- 詞向量-LRWE模型-更好地識別反義詞同義詞 2017-07-26
- 從棧不平衡問題 理解 calling convention 2017-07-26
- php imagemagick 處理 圖片剪切、壓縮、合并、插入文本、背景色透明 2017-07-26
- Swift實現(xiàn)JSON轉Model - HandyJSON使用講解 2017-07-26
- 阿里移動安全 Android端惡意鎖屏勒索應用分析 2017-07-26
- 集合結合數(shù)據(jù)結構來看看(二) 2017-07-26