MySQL 資料量太大怎麼提公升查詢效能?

2021-10-06 14:24:54 字數 2416 閱讀 2928

比如隨著業務的發展,訂單表的資料量越來越大,這個時候查詢變慢了,我們可以採取什麼措施來提公升查詢效能呢?

當單錶的訂單資料太多,多到影響效能的時候,首選的方案是,歸檔歷史訂單。

所謂歸檔,其實也是一種拆分資料的策略。簡單地說,就是把大量的歷史訂單移到另外一張歷史訂單表中。為什麼這麼做呢?因為像訂單這類具有時間屬性的資料,都存在熱尾效應。大多數情況下訪問的都是最近的資料,但訂單表裡面大量的資料都是不怎麼常用的老資料。因為新資料只佔資料總量中很少的一部分,所以把新老資料分開之後,新資料的資料量就會少很多,查詢速度也就會快很多。老資料雖然和之前比起來沒少多少,查詢速度提公升不明顯,但是,因為老資料很少會被訪問到,所以慢一點兒也問題不大。

這樣拆分的另外乙個好處是,拆分訂單時,需要改動的**非常少。大部分對訂單表的操作都是在訂單完成之前,這些業務邏輯都是完全不用修改的。即使像退貨退款這類訂單完成後的操作,也是有時限的,那這些業務邏輯也不需要修改,原來該怎麼操作訂單表還怎麼操作。基本上只有查詢統計類的功能,會查到歷史訂單,這些需要稍微做一些調整,按照時間,選擇去訂單表還是歷史訂單表查詢就可以了。很多電商大廠在它逐步發展壯大的過程中,都用這種訂單拆分的方案撐了好多年。

在考慮到底是分庫還是分表之前,我們需要先明確乙個原則,那就是能不拆就不拆,能少拆不多拆。原因也很簡單,你把資料拆分得越散,開發和維護起來就越麻煩,系統出問題的概率就越大。

分庫分表的目的是解決兩個問題:

1、資料量太大查詢慢。解決查詢慢,只要減少每次查詢的資料總量就可以了,也就是說,分表就可以解決問題。

2、應對高併發。乙個資料庫例項撐不住,就把併發請求分散到多個例項中去,所以,解決高併發的問題是需要分庫的。

簡單地說,資料量大,就分表;併發高,就分庫。一般情況下,我們的方案都需要同時做分庫分表,這時候分多少個庫,多少張表,分別用預估的併發量和資料量來計算就可以了。

如何選擇 sharding key?

選擇sharding key最重要的參考因素是,我們的業務是如何訪問資料的。選擇sharding key的時候,一定要能相容業務最常用的查詢條件,讓查詢盡量落在乙個分片中,分片之後無法相容的查詢,可以把資料同步到其他儲存中去,來解決這個問題。

如何選擇分片演算法?

1. 範圍分片

比如訂單表中分12個分片,每個月乙個分片,這樣對查詢的相容要好多,畢竟查詢條件中帶上時間範圍,讓查詢只落到某乙個分片上,還是比較容易的,我在查詢介面上強制使用者必須指定時間範圍就行了。這種做法有個很大的問題,比如現在是 3 月份,那基本上所有的查詢都集中在 3 月份這個分片上,其他 11 個分片都閒著,這樣不僅浪費資源,很可能你 3 月那個分片根本抗不住幾乎全部的併發請求。這個問題就是「熱點問題」。

基於範圍來分片容易產生熱點問題,不適合作為訂單的分片方法,但是這種分片方法的優點也很突出,那就是對查詢非常友好,基本上只要加上乙個時間範圍的查詢條件,原來該怎麼查,分片之後還可以怎麼查。範圍分片特別適合那種資料量非常大,但併發訪問量不大的 tob 系統。比如說,電信運營商的監控系統,它可能要採集所有人手機的訊號質量,然後做一些分析,這個資料量非常大,但是這個系統的使用者是運營商的工作人員,併發量很少。這種情況下就很適合範圍分片。

2. 雜湊分片

雜湊分片比較容易把資料和查詢均勻地分布到所有分片中。一般來說,訂單表都採用更均勻的雜湊分片演算法。比如說,我們要分 24 個分片,選定了 sharding key 是使用者 id,那我們決定某個使用者的訂單應該落到那個分片上的演算法是,拿使用者 id 除以 24,得到的餘數就是分片號。這是最簡單的取模演算法,一般就可以滿足大部分要求了。當然也有一些更複雜的雜湊演算法,像一致性雜湊之類的,特殊情況下也可以使用。需要注意的一點是,雜湊分片演算法能夠分得足夠均勻的前提條件是,使用者 id 後幾位數字必須是均勻分布的。比如說,你在生成使用者 id 的時候,自定義了乙個使用者 id 的規則,最後一位 0 是男性,1 是女性,這樣的使用者 id 雜湊出來可能就沒那麼均勻,可能會出現熱點。

實際案例:對於訂單表進行分庫分表,一般按照使用者 id 作為 sharding key,採用雜湊分片演算法來均勻分布使用者訂單資料。為了能支援按訂單號查詢的需求,需要把使用者 id 的後幾位放到訂單號中去。
3. 查表法

思考:「歸檔歷史訂單」的資料拆分方法,和直接進行分庫分表相比,比如說按照訂單建立時間,自動拆分成每個月一張表,兩種方法各有什麼優點和缺點?

請教,需要處理的資料量太大怎麼辦

請教,需要處理的資料量太大怎麼辦?情況是這樣的 資料庫中有幾個表,每個表記錄都超過10萬條,在查詢時需要交叉連線查詢 outer join 三個表,這就造成資料庫會生成一千萬條以上記錄的情況,所以這樣每查詢一次都需要兩秒以上時間.像這樣的查詢客戶每次請求都需要執行好幾百次,所以要等十幾分鐘才能結束....

解決get提交資料量太大的問題

由於引數中是base64編碼後的資料,比較大,導致get請求失敗,提示資料太大。get最大是256b,post是2m。解決方式 使用偽post方式 上傳方法 function picupload var ocrimagesrc document.queryselector ocr img child...

mysql大資料量處理

2008 07 11 10 41 58 分類 mysql 舉報 字型大小訂閱 以下是個人的總結,有不對的地方大家指點 設計上 冗餘 有些能冗餘的就冗餘吧,盡量少關聯表 垂直分割槽,一條記錄中有text,varchar 這些能拆出來就拆出來,能用小的型別就用小的型別,如 char替換varchar之類...