日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

MySQL性能,杀疯了

發布時間:2025/3/15 数据库 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MySQL性能,杀疯了 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

今天,我們就來到了MySQL的最后一部分——MySQL性能!

下圖是我們涉及到的知識點,主要也是根據我們實際工作中運用比較多,或者經常遇到的問題提出的。相比之前的理論知識,可以說實用性和實戰性非常強了!

MySQL上手起來其實很快,但是要深入研究還是不容易,性能調優就是最大的攔路虎,搞定了這只攔路虎,我們就能把MySQL運用自如了。

好了,話不多說,現在,我們就繼續來體驗這場MySQL的沉浸式面試吧!

性能常識和調優思路

MySQL性能怎么樣?

嗯……我之前做過測試,在MySQL5.5版本,普通8核16G的機器,一張100萬的常規表,順序寫性能2000tps讀性能的話,如果索引有效,tps在5000左右。

當然,實際性能取決于表結構、SQL語句以及索引過濾等具體情況,需要以測試結果為準。

不同版本的MySQL性能差距非常大,不同云廠商提供MySQL做的優化也不盡相同,不同業務數據模型也有區別,只有經過測試的數據才有意義。

下圖是ucloud團隊針對MySQL的基礎測試,我們在實際使用中最好也實測一下。

那下面來談談MySQL的調優思路吧。

主要有三個維度:首先,針對SQL語句進行優化,包括索引優化、特定查詢優化;其次,是對頻率控制優化,包括讀緩存,寫緩沖;最后,如果規模過大,就分庫分表。

那要怎么找到MySQL執行慢的語句呢?

我們可以看慢查詢日志,它是MySQL提供的一種日志記錄,用來記錄在MySQL中響應時間超過閥值的語句,這個閾值通常默認為10s,也可以按需配置。

Mysql是默認關閉慢查詢日志的,所以需要我們手動開啟。

那找到慢語句之后,怎么查看它的執行計劃?

使用explain命令,它可以獲取到MySQL語句的執行計劃 ,包括會使用的索引、掃描行數、表如何連接等信息。

通過這個命令,我們很容易就看出一條語句是否使用了我們預期的索引,并進行相應的調整。

怎么調整呢?

數據是在不斷變化的,同時執行器也有判斷失誤的情況,MySQL有時候的執行計劃,會出乎意料。

這種情況,我們可以使用語句強行指定索引:

select xx from table_name force index (index_name) where ...

那MySQL索引對性能影響大嗎?

索引可以說是給MySQL的性能插上了翅膀。沒有索引查找一個Key時間復雜度需要O(n),有索引就降低到了O(logn)

在數據少的時候還不明顯,多一些數據,比如100萬條數據,不走索引需要遍歷100萬條數據,如果能走索引,只需要查找1000條數據。所以有無索引,性能天差地別。

MySQL如果查詢壓力太大該怎么辦?

如果SQL語句已經足夠優秀。那么就看請求壓力是否符合二八原則,也就是說80%的壓力都集中在20%的數據。

如果是,我們可以增加一層緩存,常用的實現是在MySQL前加個Redis緩存。當然,如果實在太大了,那么只能考慮分庫分表啦。

如果是寫入壓力太大呢?

寫緩沖。一般而言可以增加消息隊列來緩解。這樣做有兩個好處,一個是緩解數據庫壓力,第二個可以控制消費頻率。

性能實戰

如果發現線上Insert導致cpu很高,你會怎么解決?

1.查看是不是請求量突然飆升導致,如果是攻擊,則增加對應的防護;

2.查看是否因為數據規模達到一個閾值,導致MySQL的處理能力發生了下降;

3.查看二級索引是否建立過多,這種情況需要去清理非必要索引。

為什么二級索引過多,會導致性能下降?

因為一個二級索引,就相當于一棵B+樹。如果我們建了10個索引,這10個索引就相當于10次隨機I/O,那粗略估算性能至少也會慢10倍

分頁操作為什么在offset過大的時候會很慢?

以offset 10000, limit 10為例。慢的原因有兩點:第一,由于offset是其實就是先找到第幾大的數字,因此沒法使用樹的結構來快速檢索。只能使用底層鏈表順序找10000個節點,時間復雜度O(n)

其次,即使這10000個節點是不需要的,MySQL也會通過二級索引上的主鍵id,去聚簇索引上查一遍數據,這可是10000次隨機I/O,自然慢成哈士奇。這和它的優化器有關系,也算是MySQL的一個大坑,時至今日,也沒有優化。

那我們怎么優化呢?

一般有兩種優化方案:

方案一:繞過去。將分頁替換為上一頁、下一頁。這樣子就可以通過和上次返回數據進行比較,搭上樹索引的便車。在ios,android端,上下頁是很常見的。

方案二:正面剛。有一個概念叫索引覆蓋,就是當輔助索引查詢的數據只有主鍵id和輔助索引本身,那么就不必再去查聚簇索引。

如此一來,減少了offset時10000次隨機I/O,只有limit出來的10個主鍵id會去查詢聚簇索引,這樣只會十次隨機I/O,可以大幅提升性能,通常能滿足業務要求。

那你說一下這兩種方式的優缺點吧。

本質上來說,上下頁方案屬于產品設計優化。索引覆蓋是技術方案優化。

上下頁方案能利用樹的分支結構實現快速過濾,還能直接通過主鍵索引查找,性能會高很多。但是它的使用場景受限,而且把主鍵ID暴露了。

索引覆蓋方案維持了分頁需求,適用場景更大,性能也提升了不少,但二級索引還是會走下層鏈表遍歷。

如果產品本身,可以接受上下頁頁面結構,且沒用其它過濾條件,可以用方案一。方案二更具有普適性,同時由于合理分表的大小,一般也就500w,二級索引上O(n)的查找損耗,通常也在可接受范圍。

針對分頁性能問題,《高性能MySQL》中提到了這兩個方案,感興趣的小伙伴可以去看看。如果想成為高級工程師,那么不僅要知道怎么做,還需要對兩者的優缺點進行對比,闡述選型思路。

Count操作的性能怎么優化?

有幾種查詢場景通用性優化方案。

第一種,是用Redis緩存來計數。每次服務啟動,就將個數加載進Redis,當然,無論是Cache Aside還是Write Through,緩存和存儲之間都會存在偏差,可以考慮用一個離線任務來矯正Redis中的個數。這種方案適用于對數據精確度,要求不是特別高的場景

第二種,為count的篩選條件建立聯合索引。這樣可以實現索引覆蓋,在二級索引表中就可以得到結果,不用再回表,回表可是O(n)次隨機I/O呢。這種方案適用于有where條件的情況,并且與其它方案不沖突,可共同使用

第三種,可以多維護一個計數表,通過事務的原子性,維持一個準確的計數。這種方案適用于對數據精度高,讀多寫少場景

你對MySQL分表有了解嗎?

隨著業務持續擴張,單表性能一定會達到極限,分表是把一個數據庫中的數據表拆分成多張表,通過分布式思路提供可擴展的性能。

那有哪些分表方式?

通常來說有水平分表、垂直分表兩種劃分方式。

垂直分表將一張表的數據,根據場景切分成多張表,本質是由于前期抽象不足,需要將業務數據進一步拆分。

水平分表則是將一張大表拆成多個結構相同的子表。直觀來看表結構都是一樣的,可以按某個字段來進行業務劃分,也可以按照數據量來劃分,劃分的規則實際就是按某種維度,預判數據量進行拆分。

那你做過的項目中,分表邏輯怎么實現的?

分表邏輯一定是在一個公共的,可復用的位置來實現。我之前做的項目,是實現了一個本地依賴包,即將分表邏輯寫在公共的代碼庫里,每個需要調用服務的客戶方都集成該公共包,就接入了自動分表的能力。

優點在于簡單,不引入新的組件,不增加運維難度。缺點是公共包更改后每個客戶端都需要更新。

能說出優缺點,說明對方案還是比較清楚的。如果想更進一步加分,需要有競爭方案,比如分表是常規地通過中間件,還是放公共包。

小伙伴們日常多結合自己的項目思考,可以說是自己業務有特殊性,比如需要二維分表,很多中間件不支持,也可以說分表邏輯經過評估,是比較固定的,為此引入新的組件反而成本更大,自圓其說,才能凸顯能力。

這里給大家推薦一個開源組件——Mycat,它是一個優秀的數據庫中間件,其本質就是提供代理服務,對數據庫進行訪問,提供包括讀寫分離、分庫分表等能力。

部署容易,耦合性低,感興趣的朋友可以了解一下。

如果初期沒做分表,已有3000W數據,此時要分庫分表怎么做?

最復雜的情況,持續比較大的訪問流量下,并且要求不停服。我們可以分幾個階段來操作:

1. 雙寫讀老階段:通過中間件,對write sql同時進行兩次轉發,也就是雙寫,保持新數據一致,同時開始歷史數據拷貝。本階段建議施行一周;

2. 雙寫雙讀階段:采用灰度策略,一部分流量讀老表,一部分流量讀新表,讀新表的部分在一開始,還可以同時多讀一次老表數據,進行比對檢查,觀察無誤后,隨著時間慢慢切量到新表。本階段建議施行至少兩周;

3. 雙寫讀新階段:此時基本已經穩定,可以只讀新表,為了安全保證,建議還是多雙寫一段時間,防止有問題遺漏。本階段建議周期一個月;

4. 寫新讀新階段:此時已經完成了分表的遷移,老表數據可以做個冷備

看著很簡單的四個步驟,但在業務量已經比較龐大的情況下,操作也是非常復雜的。首先為了安全,每一階段通常需要比較大的流轉時間,也就是說可能已經跨越了多個開發版本。

其次是會帶來短期性能損失——無論是雙寫,還是讀檢查,都做了額外的數據請求。在同樣的請求量下,服務響應時間至少增大了一倍。


面試點評

MySQL的性能測試與調優,是MySQL常見但又高階的內容,深入理解MySQL的性能與調優,才能良好的勝任相關開發與維護工作。

有道無術,術可成;有術無道,止于術

歡迎大家關注Java之道公眾號

好文章,我在看??

新人創作打卡挑戰賽發博客就能抽獎!定制產品紅包拿不停!

總結

以上是生活随笔為你收集整理的MySQL性能,杀疯了的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。