講一講MySQL如何防止「老鼠屎」型別的SQL語句

2021-09-07 20:39:53 字數 1414 閱讀 3627

原諒我標題黨了

當然不可能有哪乙個sql語句會這麼出名,以至於大家叫它「老鼠屎」;但是有一些sql語句確實主是做著這樣的事;由於程式的

區域性性原理,資料庫會把常用的資料快取到記憶體中,對於這種場景通常是使用lru演算法。

原生的lru演算法有空子

這裡不是說lru演算法有bug、只是說它在資料庫這個場景下是有「問題」的,lru演算法本來是為了盡可能的把「熱」資料儲存在記憶體裡。

資料表結構如果設計的不好的話就可能使得一些語句要走全表掃瞄,我們假設在「全表掃瞄」執行之前lru中的資料是「熱」的,由於

「全表掃瞄」會把大量的資料載入到記憶體,載入多少新的資料就會「淘汰」同等數量的「熱」資料。真正的問題就在於因「全表掃瞄」而載入

到記憶體的資料可能再也不用了,也就是說因「全表掃瞄」而載入的資料大多數情況下是冷的;那麼「全表掃瞄」語句就鑄成了這樣乙個客戶

的事實 ---- 全表掃瞄淘汰了大量的熱資料,換來的只是載入了同等數量的冷資料。

mysql對lru演算法的改進

mysql對原生的lru演算法進行了改進、它把原生的lru列表在邏輯上分成了兩段,前面的5/8頁面用來儲存熱資料,後面的3/8用來儲存

「溫」資料。 為什麼說這3/8是「溫」資料呢? 當有新的資料(頁面)要載入記憶體時,這些資料會先被插入到「溫」列表的頂部,如果這個時候

「溫」列表的已經滿了那麼「溫」列表底部資料(頁面)就會被淘汰以容納新的資料(頁面)。也就是說「溫」列表是乙個正常的lru列表,那資料

什麼時候會被調入到「熱」列表呢?而是從問題入手,因「全表掃瞄」而載入記憶體的語句通常只會被訪問一次,而其它sql載入的頁面可能

要被多次的訪問。解決方案就有了如果乙個頁面被調入「溫」列表之後再也沒有被訪問那麼它就不會被調入「熱」列表,如果乙個目前在「溫」

列表中的時候又被訪問了一次那麼這個頁面就會被調入「熱」列表。dba也可以手工設定「溫」列表佔整個列表的比較innodb_old_blocks_pct

引數就是做這個事的,預設值是37是乙個非常直接3/8*100 (0.375*100)的值

就算mysql對lru演算法做了這個優化,不過還是有乙個小問題;比如說我現在的主機是512g的資料庫400g給了buffer pool 乙個400g

的buffer pool 「溫」列表也就有150g的大小;150g大小的列表如果乙個頁面從進入「溫」列表頂部到它慢慢的被移到底部這個可能半個小時

過去了,如果這個時候它剛好被訪問了一次,這下就不得了了,平地一聲雷它要上天啦,它會被直接調到「熱」列表的頂部!這個明顯不是

dba想要看到的結果。 mysql針對這個也做了優化innodb_old_blocks_time這個引數用來控制時間維度,如果頁面的第二次訪問的時間

超過了innodb_old_blocks_time設定的值那麼頁面不會被調入「熱」列表。

講一講IP位址

ip位址組成ip位址分類 為了適應不同的網路,ip位址空間被分為5類,分別是a,b,c,d和e類,其中a,b,c類最常用,d類用於組播,e類用於科研。從上述 中可以看到,每個網路中的主機數都是2 主機位 2,那是因為網路中有一些位址被保留,不能分配給網路使用,有哪些保留位址呢?其實主要有兩類,一類叫...

MySQL第一講概論

mysql 後期內容 python 今日內容概要 mysql的概念 資料庫軟體的安裝及使用 配置檔案介紹 資料庫常用命令 庫操作 表操作 記錄操作 今日內容詳細 什麼是資料庫 1.單機遊戲 本地儲存本地讀取 紅警使用者名稱和密碼 遊戲進度都只能在自己的計算機上有效 2.聯網遊戲 資料是共享的 所有人...

講一講抽象工廠模式

1.新建產品族介面 我這裡可以理解為生產乙個產品需要兩個步驟 步驟1 public inte ce iproduct1 步驟2 public inte ce iproduct2 2.新建工廠介面 乙個工廠生產乙個產品都需要這兩個步驟 public inte ce ifactory 3.新建各個產品的...