91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

當(dāng)MySQL單表記錄數(shù)過(guò)大時(shí),增刪改查性能都會(huì)急劇下降

jf_TEuU2tls ? 來(lái)源:浩道linux ? 作者:低至一折起 ? 2022-12-15 11:44 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

當(dāng)MySQL單表記錄數(shù)過(guò)大時(shí),增刪改查性能都會(huì)急劇下降

單表優(yōu)化

除非單表數(shù)據(jù)未來(lái)會(huì)一直不斷上漲,否則不要一開(kāi)始就考慮拆分,拆分會(huì)帶來(lái)邏輯、部署、運(yùn)維的各種復(fù)雜度,一般以整型值為主的表在千萬(wàn)級(jí)以下,字符串為主的表在五百萬(wàn)以下是沒(méi)有太大問(wèn)題的。

而事實(shí)上很多時(shí)候 MySQL 單表的性能依然有不少優(yōu)化空間,甚至能正常支撐千萬(wàn)級(jí)以上的數(shù)據(jù)量。

字段

  • 盡量使用 TINYINT、 SMALLINT、 MEDIUM_INT 作為整數(shù)類(lèi)型而非 INT,如果非負(fù)則加上 UNSIGNED

  • VARCHAR 的長(zhǎng)度只分配真正需要的空間

  • 使用枚舉或整數(shù)代替字符串類(lèi)型

  • 盡量使用 TIMESTAMP 而非 DATETIME

  • 單表不要有太多字段,建議在 20 以內(nèi)

  • 避免使用 NULL 字段,很難查詢優(yōu)化且占用額外索引空間

  • 用整型來(lái)存 IP

索引

  • 索引并不是越多越好,要根據(jù)查詢有針對(duì)性的創(chuàng)建,考慮在 WHERE 和 ORDER BY

  • 命令上涉及的列建立索引,可根據(jù) EXPLAIN 來(lái)查看是否用了索引還是全表掃描

  • 應(yīng)盡量避免在 WHERE 子句中對(duì)字段進(jìn)行 NULL 值判斷,否則將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描

  • 值分布很稀少的字段不適合建索引,例如"性別"這種只有兩三個(gè)值的字段

  • 字符字段只建前綴索引

  • 字符字段最好不要做主鍵

  • 不用外鍵,由程序保證約束

  • 盡量不用 UNIQUE,由程序保證約束

  • 使用多列索引時(shí)主意順序和查詢條件保持一致,同時(shí)刪除不必要的單列索引

查詢SQL

  • 可通過(guò)開(kāi)啟慢查詢?nèi)罩緛?lái)找出較慢的 SQL

  • 不做列運(yùn)算:SELECT id WHERE age+1=10,任何對(duì)列的操作都將導(dǎo)致表掃描,它包括數(shù)據(jù)庫(kù)教程函數(shù)、計(jì)算表達(dá)式等等,查詢時(shí)要盡可能將操作移至等號(hào)右邊

  • sql 語(yǔ)句盡可能簡(jiǎn)單:一條 sql 只能在一個(gè) cpu 運(yùn)算;大語(yǔ)句拆小語(yǔ)句,減少鎖時(shí)間;一條大sql 可以堵死整個(gè)庫(kù)

  • 不用 SELECT *

  • OR 改寫(xiě)成 IN:OR 的效率是 n 級(jí)別, IN 的效率是 log(n) 級(jí)別,IN 的個(gè)數(shù)建議控制在 200 以內(nèi)

  • 不用函數(shù)和觸發(fā)器,在應(yīng)用程序?qū)崿F(xiàn)

  • 避免 %xxx 式查詢

  • 少用 JOIN

  • 使用同類(lèi)型進(jìn)行比較,比如用 '123' 和 '123' 比, 123 和 123 比

  • 盡量避免在 WHERE 子句中使用 != 或 <> 操作符,否則將引擎放棄使用索引而進(jìn)行全表掃描

  • 對(duì)于連續(xù)數(shù)值,使用 BETWEEN 不用 IN:SELECT id FROM t WHERE num BETWEEN 1 AND 5

  • 列表數(shù)據(jù)不要拿全表,要使用 LIMIT 來(lái)分頁(yè),每頁(yè)數(shù)量也不要太大

引擎

目前廣泛使用的是 MyISAM 和 InnoDB 兩種引擎:

MyISAM

MyISAM 引擎是 MySQL 5.1 及之前版本的默認(rèn)引擎,它的特點(diǎn)是:

  • 不支持行鎖,讀取時(shí)對(duì)需要讀到的所有表加鎖,寫(xiě)入時(shí)則對(duì)表加排它鎖

  • 不支持事務(wù)

  • 不支持外鍵

  • 不支持崩潰后的安全恢復(fù)

  • 在表有讀取查詢的同時(shí),支持往表中插入新紀(jì)錄

  • 支持 BLOB 和 TEXT 的前 500 個(gè)字符索引,支持全文索引

  • 支持延遲更新索引,極大提升寫(xiě)入性能

  • 對(duì)于不會(huì)進(jìn)行修改的表,支持壓縮表,極大減少磁盤(pán)空間占用

InnoDB

InnoDB 在 MySQL 5.5 后成為默認(rèn)索引,它的特點(diǎn)是:

  • 支持行鎖,采用 MVCC 來(lái)支持高并發(fā)

  • 支持事務(wù)

  • 支持外鍵

  • 支持崩潰后的安全恢復(fù)

  • 不支持全文索引(5.6.4之后版本逐漸開(kāi)始支持)

總體來(lái)講,MyISAM 適合 SELECT 密集型的表,而 InnoDB 適合 INSERT 和 UPDATE 密集型的表

系統(tǒng)調(diào)優(yōu)參數(shù)

可以使用下面幾個(gè)工具來(lái)做基準(zhǔn)測(cè)試:

  • sysbench:一個(gè)模塊化,跨平臺(tái)以及多線程的性能測(cè)試工具

  • iibench-mysql:基于 Java 的 MySQL/Percona/MariaDB 索引進(jìn)行插入性能測(cè)試工具

  • tpcc-mysql:Percona 開(kāi)發(fā)的 TPC-C 測(cè)試工具

具體的調(diào)優(yōu)參數(shù)內(nèi)容較多,具體可參考官方文檔,這里介紹一些比較重要的參數(shù):

  • backlog:backlog 值指出在 MySQL 暫時(shí)停止回答新請(qǐng)求之前的短時(shí)間內(nèi)多少個(gè)請(qǐng)求可以被存在堆棧中。也就是說(shuō),如果 MySql 的連接數(shù)據(jù)達(dá)到 maxconnections 時(shí),新來(lái)的請(qǐng)求將會(huì)被存在堆棧中,以等待某一連接釋放資源,該堆棧的數(shù)量即 backlog,如果等待連接的數(shù)量超過(guò)back_log,將不被授予連接資源??梢詮哪J(rèn)的 50 升至 500

  • wait_timeout:數(shù)據(jù)庫(kù)連接閑置時(shí)間,閑置連接會(huì)占用內(nèi)存資源??梢詮哪J(rèn)的 8 小時(shí)減到半小時(shí)

  • maxuserconnection:最大連接數(shù),默認(rèn)為 0 無(wú)上限,最好設(shè)一個(gè)合理上限

  • thread_concurrency:并發(fā)線程數(shù),設(shè)為 CPU 核數(shù)的兩倍

  • skipnameresolve:禁止對(duì)外部連接進(jìn)行 DNS 解析,消除 DNS 解析時(shí)間,但需要所有遠(yuǎn)程主機(jī)用 IP 訪問(wèn)

  • keybuffersize:索引塊的緩存大小,增加會(huì)提升索引處理速度,對(duì) MyISAM 表性能影響最大。對(duì)于內(nèi)存 4G 左右,可設(shè)為 256M 或 384M,通過(guò)查詢show status like'key_read%',保證 key_reads / key_read_requests 在 0.1% 以下最好

  • innodbbufferpool_size:緩存數(shù)據(jù)塊和索引塊,對(duì) InnoDB 表性能影響最大。通過(guò)查詢show status like'Innodb_buffer_pool_read%',保證(Innodb_buffer_pool_read_requests –
    Innodb_buffer_pool_reads) / Innodb_buffer_pool_read_requests
    越高越好

  • innodbadditionalmempoolsize:InnoDB 存儲(chǔ)引擎用來(lái)存放數(shù)據(jù)字典信息以及一些內(nèi)部數(shù)據(jù)結(jié)構(gòu)的內(nèi)存空間大小,當(dāng)數(shù)據(jù)庫(kù)對(duì)象非常多的時(shí)候,適當(dāng)調(diào)整該參數(shù)的大小以確保所有數(shù)據(jù)都能存放在內(nèi)存中提高訪問(wèn)效率,當(dāng)過(guò)小的時(shí)候,MySQL 會(huì)記錄 Warning 信息到數(shù)據(jù)庫(kù)的錯(cuò)誤日志中,這時(shí)就需要該調(diào)整這個(gè)參數(shù)大小

  • innodblogbuffer_size:InnoDB 存儲(chǔ)引擎的事務(wù)日志所使用的緩沖區(qū),一般來(lái)說(shuō)不建議超過(guò)
    32MB

  • querycachesize:緩存 MySQL 中的 ResultSet,也就是一條 SQL 語(yǔ)句執(zhí)行的結(jié)果集,所以僅僅只能針對(duì) select 語(yǔ)句。當(dāng)某個(gè)表的數(shù)據(jù)有任何任何變化,都會(huì)導(dǎo)致所有引用了該表的select 語(yǔ)句在 Query Cache 中的緩存數(shù)據(jù)失效。所以,當(dāng)我們的數(shù)據(jù)變化非常頻繁的情況下,使用 Query Cache 可能會(huì)得不償失。根據(jù)命中率(Qcache_hits / (Qcache_hits + Qcache_inserts) * 100))進(jìn)行調(diào)整,一般不建議太大,256MB 可能已經(jīng)差不多了,大型的配置型靜態(tài)數(shù)據(jù)可適當(dāng)調(diào)大. 可以通過(guò)命令show status like'Qcache_%'查看目前系統(tǒng) Query Catch 使用大小

  • readbuffersize:MySql 讀入緩沖區(qū)大小。對(duì)表進(jìn)行順序掃描的請(qǐng)求將分配一個(gè)讀入緩沖區(qū),MySql 會(huì)為它分配一段內(nèi)存緩沖區(qū)。如果對(duì)表的順序掃描請(qǐng)求非常頻繁,可以通過(guò)增加該變量值以及內(nèi)存緩沖區(qū)大小提高其性能

  • sortbuffersize:MySql 執(zhí)行排序使用的緩沖大小。如果想要增加 ORDER BY 的速度,首先看是否可以讓 MySQL 使用索引而不是額外的排序階段。如果不能,可以嘗試增加 sortbuffersize 變量的大小

  • readrndbuffer_size:MySql 的隨機(jī)讀緩沖區(qū)大小。當(dāng)按任意順序讀取行時(shí)(例如,按照排序順序),將分配一個(gè)隨機(jī)讀緩存區(qū)。進(jìn)行排序查詢時(shí),MySql 會(huì)首先掃描一遍該緩沖,以避免磁盤(pán)搜索,提高查詢速度,如果需要排序大量數(shù)據(jù),可適當(dāng)調(diào)高該值。但 MySql 會(huì)為每個(gè)客戶連接發(fā)放該緩沖空間,所以應(yīng)盡量適當(dāng)設(shè)置該值,以避免內(nèi)存開(kāi)銷(xiāo)過(guò)大

  • record_buffer:每個(gè)進(jìn)行一個(gè)順序掃描的線程為其掃描的每張表分配這個(gè)大小的一個(gè)緩沖區(qū)。如果你做很多順序掃描,可能想要增加該值

  • threadcachesize:保存當(dāng)前沒(méi)有與連接關(guān)聯(lián)但是準(zhǔn)備為后面新的連接服務(wù)的線程,可以快速響應(yīng)連接的線程請(qǐng)求而無(wú)需創(chuàng)建新的

  • tablecache:類(lèi)似于 threadcache_size,但用來(lái)緩存表文件,對(duì) InnoDB 效果不大,主要用于 MyISAM

升級(jí)硬件

Scale up,這個(gè)不多說(shuō)了,根據(jù) MySQL 是 CPU 密集型還是 I/O 密集型,通過(guò)提升 CPU 和內(nèi)存、使用 SSD,都能顯著提升 MySQL 性能。

讀寫(xiě)分離

也是目前常用的優(yōu)化,從庫(kù)讀主庫(kù)寫(xiě),一般不要采用雙主或多主引入很多復(fù)雜性,盡量采用文中的其他方案來(lái)提高性能。

同時(shí)目前很多拆分的解決方案同時(shí)也兼顧考慮了讀寫(xiě)分離。

緩存

緩存可以發(fā)生在這些層次:

  • MySQL 內(nèi)部:在系統(tǒng)調(diào)優(yōu)參數(shù)介紹了相關(guān)設(shè)置

  • 數(shù)據(jù)訪問(wèn)層:比如 MyBatis 針對(duì) SQL 語(yǔ)句做緩存,而 Hibernate 可以精確到單個(gè)記錄,這里緩存的對(duì)象主要是持久化對(duì)象 PersistenceObject

  • 應(yīng)用服務(wù)層:這里可以通過(guò)編程手段對(duì)緩存做到更精準(zhǔn)的控制和更多的實(shí)現(xiàn)策略,這里緩存的對(duì)象是數(shù)據(jù)傳輸對(duì)象 DataTransferObject(DTO)

  • Web 層:針對(duì) web 頁(yè)面做緩存

  • 瀏覽器客戶端:用戶端的緩存

可以根據(jù)實(shí)際情況在一個(gè)層次或多個(gè)層次結(jié)合加入緩存。

這里重點(diǎn)介紹下服務(wù)層的緩存實(shí)現(xiàn),目前主要有兩種方式:

  • 直寫(xiě)式(Write Through):在數(shù)據(jù)寫(xiě)入數(shù)據(jù)庫(kù)后,同時(shí)更新緩存,維持?jǐn)?shù)據(jù)庫(kù)與緩存的一致性。這也是當(dāng)前大多數(shù)應(yīng)用緩存框架如 Spring Cache 的工作方式。這種實(shí)現(xiàn)非常簡(jiǎn)單,同步好,但效率一般。

  • 回寫(xiě)式(Write Back):當(dāng)有數(shù)據(jù)要寫(xiě)入數(shù)據(jù)庫(kù)時(shí),只會(huì)更新緩存,然后異步批量的將緩存數(shù)據(jù)同步到數(shù)據(jù)庫(kù)上。這種實(shí)現(xiàn)比較復(fù)雜,需要較多的應(yīng)用邏輯,同時(shí)可能會(huì)產(chǎn)生數(shù)據(jù)庫(kù)與緩存的不同步,但效率非常高。

表分區(qū)

MySQL 在 5.1 版引入的分區(qū)是一種簡(jiǎn)單的水平拆分,用戶需要在建表的時(shí)候加上分區(qū)參數(shù),對(duì)應(yīng)用是透明的無(wú)需修改代碼

對(duì)用戶來(lái)說(shuō),分區(qū)表是一個(gè)獨(dú)立的邏輯表,但是底層由多個(gè)物理子表組成,實(shí)現(xiàn)分區(qū)的代碼實(shí)際上是通過(guò)對(duì)一組底層表的對(duì)象封裝,但對(duì) SQL 層來(lái)說(shuō)是一個(gè)完全封裝底層的黑盒子。MySQL 實(shí)現(xiàn)分區(qū)的方式也意味著索引也是按照分區(qū)的子表定義,沒(méi)有全局索引。

327c7444-7c19-11ed-8abf-dac502259ad0.jpg

用戶的 SQL 語(yǔ)句是需要針對(duì)分區(qū)表做優(yōu)化,SQL 條件中要帶上分區(qū)條件的列,從而使查詢定位到少量的分區(qū)上,否則就會(huì)掃描全部分區(qū),可以通過(guò) EXPLAIN PARTITIONS 來(lái)查看某條SQL 語(yǔ)句會(huì)落在那些分區(qū)上,從而進(jìn)行 SQL 優(yōu)化,如下圖 5 條記錄落在兩個(gè)分區(qū)上:

328bbb0c-7c19-11ed-8abf-dac502259ad0.jpg

分區(qū)的好處是:

  • 可以讓單表存儲(chǔ)更多的數(shù)據(jù)

  • 分區(qū)表的數(shù)據(jù)更容易維護(hù),可以通過(guò)清楚整個(gè)分區(qū)批量刪除大量數(shù)據(jù),也可以增加新的分區(qū)來(lái)支持新插入的數(shù)據(jù)。另外,還可以對(duì)一個(gè)獨(dú)立分區(qū)進(jìn)行優(yōu)化、檢查、修復(fù)等操作

  • 部分查詢能夠從查詢條件確定只落在少數(shù)分區(qū)上,速度會(huì)很快

  • 分區(qū)表的數(shù)據(jù)還可以分布在不同的物理設(shè)備上,從而高效利用多個(gè)硬件設(shè)備

  • 可以使用分區(qū)表賴避免某些特殊瓶頸,例如 InnoDB 單個(gè)索引的互斥訪問(wèn)、ext3 文件系統(tǒng)的
    inode 鎖競(jìng)爭(zhēng)

  • 可以備份和恢復(fù)單個(gè)分區(qū)

分區(qū)的限制和缺點(diǎn):

  • 一個(gè)表最多只能有 1024 個(gè)分區(qū)

  • 如果分區(qū)字段中有主鍵或者唯一索引的列,那么所有主鍵列和唯一索引列都必須包含進(jìn)來(lái)

  • 分區(qū)表無(wú)法使用外鍵約束

  • NULL 值會(huì)使分區(qū)過(guò)濾無(wú)效

  • 所有分區(qū)必須使用相同的存儲(chǔ)引擎

分區(qū)的類(lèi)型:

  • RANGE 分區(qū):基于屬于一個(gè)給定連續(xù)區(qū)間的列值,把多行分配給分區(qū)

  • LIST 分區(qū):類(lèi)似于按 RANGE 分區(qū),區(qū)別在于 LIST 分區(qū)是基于列值匹配一個(gè)離散值集合中的某個(gè)值來(lái)進(jìn)行選擇

  • HASH 分區(qū):基于用戶定義的表達(dá)式的返回值來(lái)進(jìn)行選擇的分區(qū),該表達(dá)式使用將要插入到表中的這些行的列值進(jìn)行計(jì)算。這個(gè)函數(shù)可以包含 MySQL 中有效的、產(chǎn)生非負(fù)整數(shù)值的任何表達(dá)式

  • KEY 分區(qū):類(lèi)似于按 HASH 分區(qū),區(qū)別在于 KEY 分區(qū)只支持計(jì)算一列或多列,且 MySQL 服務(wù)器提供其自身的哈希函數(shù)。必須有一列或多列包含整數(shù)值

分區(qū)適合的場(chǎng)景有:

最適合的場(chǎng)景數(shù)據(jù)的時(shí)間序列性比較強(qiáng),則可以按時(shí)間來(lái)分區(qū),如下所示:

329d551a-7c19-11ed-8abf-dac502259ad0.jpg

查詢時(shí)加上時(shí)間范圍條件效率會(huì)非常高,同時(shí)對(duì)于不需要的歷史數(shù)據(jù)能很容的批量刪除。

如果數(shù)據(jù)有明顯的熱點(diǎn),而且除了這部分?jǐn)?shù)據(jù),其他數(shù)據(jù)很少被訪問(wèn)到,那么可以將熱點(diǎn)數(shù)據(jù)單獨(dú)放在一個(gè)分區(qū),讓這個(gè)分區(qū)的數(shù)據(jù)能夠有機(jī)會(huì)都緩存在內(nèi)存中,查詢時(shí)只訪問(wèn)一個(gè)很小的分區(qū)表,能夠有效使用索引和緩存。

另外 MySQL 有一種早期的簡(jiǎn)單的分區(qū)實(shí)現(xiàn) - 合并表(merge table),限制較多且缺乏優(yōu)化,不建議使用,應(yīng)該用新的分區(qū)機(jī)制來(lái)替代

垂直拆分

垂直分庫(kù)是根據(jù)數(shù)據(jù)庫(kù)里面的數(shù)據(jù)表的相關(guān)性進(jìn)行拆分。

比如:一個(gè)數(shù)據(jù)庫(kù)里面既存在用戶數(shù)據(jù),又存在訂單數(shù)據(jù),那么垂直拆分可以把用戶數(shù)據(jù)放到用戶庫(kù)、把訂單數(shù)據(jù)放到訂單庫(kù)。

垂直分表是對(duì)數(shù)據(jù)表進(jìn)行垂直拆分的一種方式,常見(jiàn)的是把一個(gè)多字段的大表按常用字段和非常用字段進(jìn)行拆分,每個(gè)表里面的數(shù)據(jù)記錄數(shù)一般情況下是相同的,只是字段不一樣,使用主鍵關(guān)聯(lián)

比如原始的用戶表是:

32cfd6e8-7c19-11ed-8abf-dac502259ad0.jpg

垂直拆分后是:

32e31424-7c19-11ed-8abf-dac502259ad0.jpg

垂直拆分的優(yōu)點(diǎn)是:

  • 可以使得行數(shù)據(jù)變小,一個(gè)數(shù)據(jù)塊( Block )就能存放更多的數(shù)據(jù),在查詢時(shí)就會(huì)減少 I/O 次數(shù)(每次查詢時(shí)讀取的 Block 就少)

  • 可以達(dá)到最大化利用 Cache 的目的,具體在垂直拆分的時(shí)候可以將不常變的字段放一起,將經(jīng)常改變的放一起

  • 數(shù)據(jù)維護(hù)簡(jiǎn)單

缺點(diǎn)是:

  • 主鍵出現(xiàn)冗余,需要管理冗余列

  • 會(huì)引起表連接 JOIN 操作(增加 CPU 開(kāi)銷(xiāo))可以通過(guò)在業(yè)務(wù)服務(wù)器上進(jìn)行 join 來(lái)減少數(shù)據(jù)庫(kù)壓力

  • 依然存在單表數(shù)據(jù)量過(guò)大的問(wèn)題(需要水平拆分)

  • 事務(wù)處理復(fù)雜

水平拆分

概述

水平拆分是通過(guò)某種策略將數(shù)據(jù)分片來(lái)存儲(chǔ),分庫(kù)內(nèi)分表和分庫(kù)兩部分,每片數(shù)據(jù)會(huì)分散到不同的 MySQL 表或庫(kù),達(dá)到分布式的效果,能夠支持非常大的數(shù)據(jù)量。前面的表分區(qū)本質(zhì)上也是一種特殊的庫(kù)內(nèi)分表。

庫(kù)內(nèi)分表,僅僅是單純的解決了單一表數(shù)據(jù)過(guò)大的問(wèn)題,由于沒(méi)有把表的數(shù)據(jù)分布到不同的機(jī)器上,因此對(duì)于減輕 MySQL 服務(wù)器的壓力來(lái)說(shuō),并沒(méi)有太大的作用,大家還是競(jìng)爭(zhēng)同一個(gè)物理機(jī)上的 IO、CPU、網(wǎng)絡(luò),這個(gè)就要通過(guò)分庫(kù)來(lái)解決

前面垂直拆分的用戶表如果進(jìn)行水平拆分,結(jié)果是:

32f5777c-7c19-11ed-8abf-dac502259ad0.jpg

實(shí)際情況中往往會(huì)是垂直拆分和水平拆分的結(jié)合,即將 Users_A_M 和 Users_N_Z 再拆成 Users 和 UserExtras,這樣一共四張表

水平拆分的優(yōu)點(diǎn)是:

  • 不存在單庫(kù)大數(shù)據(jù)和高并發(fā)的性能瓶頸

  • 應(yīng)用端改造較少

  • 提高了系統(tǒng)的穩(wěn)定性和負(fù)載能力

缺點(diǎn)是:

  • 分片事務(wù)一致性難以解決

  • 跨節(jié)點(diǎn) Join 性能差,邏輯復(fù)雜

  • 數(shù)據(jù)多次擴(kuò)展難度跟維護(hù)量極大

分片原則

  • 能不分就不分,參考單表優(yōu)化

  • 分片數(shù)量盡量少,分片盡量均勻分布在多個(gè)數(shù)據(jù)結(jié)點(diǎn)上,因?yàn)橐粋€(gè)查詢 SQL 跨分片越多,則總體性能越差,雖然要好于所有數(shù)據(jù)在一個(gè)分片的結(jié)果,只在必要的時(shí)候進(jìn)行擴(kuò)容,增加分片數(shù)量

  • 分片規(guī)則需要慎重選擇做好提前規(guī)劃,分片規(guī)則的選擇,需要考慮數(shù)據(jù)的增長(zhǎng)模式,數(shù)據(jù)的訪問(wèn)模式,分片關(guān)聯(lián)性問(wèn)題,以及分片擴(kuò)容問(wèn)題,最近的分片策略為范圍分片,枚舉分片,一致性 Hash 分片,這幾種分片都有利于擴(kuò)容

  • 盡量不要在一個(gè)事務(wù)中的 SQL 跨越多個(gè)分片,分布式事務(wù)一直是個(gè)不好處理的問(wèn)題

  • 查詢條件盡量?jī)?yōu)化,盡量避免 Select * 的方式,大量數(shù)據(jù)結(jié)果集下,會(huì)消耗大量帶寬和
    CPU 資源,查詢盡量避免返回大量結(jié)果集,并且盡量為頻繁使用的查詢語(yǔ)句建立索引。

  • 通過(guò)數(shù)據(jù)冗余和表分區(qū)依賴降低跨庫(kù) Join 的可能

這里特別強(qiáng)調(diào)一下分片規(guī)則的選擇問(wèn)題,如果某個(gè)表的數(shù)據(jù)有明顯的時(shí)間特征,比如訂單、交易記錄等,則他們通常比較合適用時(shí)間范圍分片,因?yàn)榫哂袝r(shí)效性的數(shù)據(jù),我們往往關(guān)注其近期的數(shù)據(jù),查詢條件中往往帶有時(shí)間字段進(jìn)行過(guò)濾,比較好的方案是,當(dāng)前活躍的數(shù)據(jù),采用跨度比較短的時(shí)間段進(jìn)行分片,而歷史性的數(shù)據(jù),則采用比較長(zhǎng)的跨度存儲(chǔ)。

總體上來(lái)說(shuō),分片的選擇是取決于最頻繁的查詢 SQL 的條件,因?yàn)椴粠魏?Where 語(yǔ)句的查詢 SQL,會(huì)遍歷所有的分片,性能相對(duì)最差,因此這種 SQL 越多,對(duì)系統(tǒng)的影響越大,所以我們要盡量避免這種 SQL 的產(chǎn)生。

解決方案

由于水平拆分牽涉的邏輯比較復(fù)雜,當(dāng)前也有了不少比較成熟的解決方案。這些方案分為兩大類(lèi):

  • 客戶端架構(gòu)

  • 代理架構(gòu)

客戶端架構(gòu)

通過(guò)修改數(shù)據(jù)訪問(wèn)層,如 JDBC、Data Source、MyBatis,通過(guò)配置來(lái)管理多個(gè)數(shù)據(jù)源,直連數(shù)據(jù)庫(kù),并在模塊內(nèi)完成數(shù)據(jù)的分片整合,一般以 Jar 包的方式呈現(xiàn)

這是一個(gè)客戶端架構(gòu)的例子:

330d20d4-7c19-11ed-8abf-dac502259ad0.jpg

可以看到分片的實(shí)現(xiàn)是和應(yīng)用服務(wù)器在一起的,通過(guò)修改 Spring JDBC 層來(lái)實(shí)現(xiàn)

客戶端架構(gòu)的優(yōu)點(diǎn)是:

  • 應(yīng)用直連數(shù)據(jù)庫(kù),降低外圍系統(tǒng)依賴所帶來(lái)的宕機(jī)風(fēng)險(xiǎn)

  • 集成成本低,無(wú)需額外運(yùn)維的組件

缺點(diǎn)是:

  • 限于只能在數(shù)據(jù)庫(kù)訪問(wèn)層上做文章,擴(kuò)展性一般,對(duì)于比較復(fù)雜的系統(tǒng)可能會(huì)力不從心

  • 將分片邏輯的壓力放在應(yīng)用服務(wù)器上,造成額外風(fēng)險(xiǎn)

代理架構(gòu)

通過(guò)獨(dú)立的中間件來(lái)統(tǒng)一管理所有數(shù)據(jù)源和數(shù)據(jù)分片整合,后端數(shù)據(jù)庫(kù)集群對(duì)前端應(yīng)用程序透明,需要獨(dú)立部署和運(yùn)維代理組件

這是一個(gè)代理架構(gòu)的例子:

331e3374-7c19-11ed-8abf-dac502259ad0.jpg

代理組件為了分流和防止單點(diǎn),一般以集群形式存在,同時(shí)可能需要 Zookeeper 之類(lèi)的服務(wù)組件來(lái)管理

代理架構(gòu)的優(yōu)點(diǎn)是:

  • 能夠處理非常復(fù)雜的需求,不受數(shù)據(jù)庫(kù)訪問(wèn)層原來(lái)實(shí)現(xiàn)的限制,擴(kuò)展性強(qiáng)

  • 對(duì)于應(yīng)用服務(wù)器透明且沒(méi)有增加任何額外負(fù)載

缺點(diǎn)是:

  • 需部署和運(yùn)維獨(dú)立的代理中間件,成本高

  • 應(yīng)用需經(jīng)過(guò)代理來(lái)連接數(shù)據(jù)庫(kù),網(wǎng)絡(luò)上多了一跳,性能有損失且有額外風(fēng)險(xiǎn)

各方案比較

框架 出品方 架構(gòu)模型 支持?jǐn)?shù)據(jù)庫(kù) 分庫(kù) 分表 讀寫(xiě)分離 外部依賴 是否開(kāi)源 實(shí)現(xiàn)語(yǔ)言 支持語(yǔ)言 GitHub星數(shù)
MySQL Fabric MySQL官方 代理架構(gòu) MySQL 無(wú) python 無(wú)限制 35
Cobar 阿里巴巴 代理架構(gòu) MySQL 無(wú) 無(wú) 無(wú) Java 無(wú)限制 1287
Cobar Client 阿里巴巴 客戶端架構(gòu) MySQL 無(wú) 無(wú) 無(wú) Java Java 344
TDDL 淘寶 客戶端架構(gòu) 無(wú)限制 Diamond 只開(kāi)源部分 Java Java 519
Atlas 奇虎360 代理架構(gòu) MySQL 無(wú) C 無(wú)限制 1941
Heisenberg 百度熊照 代理架構(gòu) MySQL 無(wú) Java 無(wú)限制 197
TribeDB 個(gè)人 代理架構(gòu) MySQL 無(wú) NodeJS 無(wú)限制 126
Sharding JDBC 當(dāng)當(dāng) 客戶端架構(gòu) MySQL 無(wú) Java Java 1144
Shark 個(gè)人 客戶端架構(gòu) MySQL 無(wú) 無(wú) Java Java 84
KingShard 個(gè)人 代理架構(gòu) MySQL 無(wú) Golang 無(wú)限制 1836
OneProxy 平民軟件 代理架構(gòu) MySQL 無(wú) 未知 無(wú)限制 未知
MyCat 社區(qū) 代理架構(gòu) MySQL 無(wú) Java 無(wú)限制 1270
Vitess Youtube 代理架構(gòu) MySQL 無(wú) Golang 無(wú)限制 3636
Mixer 個(gè)人 代理架構(gòu) MySQL 無(wú) 無(wú) Golang 無(wú)限制 472
JetPants Tumblr 客戶端架構(gòu) MySQL 無(wú) 無(wú) Ruby Ruby 957
HibernateShard Hibernate 客戶端架構(gòu) 無(wú)限制 無(wú) 無(wú) Java Java 57
MybatisShard MakerSoft 客戶端架構(gòu) 無(wú)限制 無(wú) 無(wú) Java Java 119
Gizzard Twitter 代理架構(gòu) 無(wú)限制 無(wú) 無(wú) Java 無(wú)限制 2087


如此多的方案,如何進(jìn)行選擇?可以按以下思路來(lái)考慮:

  • 確定是使用代理架構(gòu)還是客戶端架構(gòu)。中小型規(guī)?;蚴潜容^簡(jiǎn)單的場(chǎng)景傾向于選擇客戶端架構(gòu),復(fù)雜場(chǎng)景或大規(guī)模系統(tǒng)傾向選擇代理架構(gòu)

  • 具體功能是否滿足,比如需要跨節(jié)點(diǎn) ORDER BY,那么支持該功能的優(yōu)先考慮

  • 不考慮一年內(nèi)沒(méi)有更新的產(chǎn)品,說(shuō)明開(kāi)發(fā)停滯,甚至無(wú)人維護(hù)和技術(shù)支持

  • 最好按大公司 -> 社區(qū) -> 小公司 -> 個(gè)人這樣的出品方順序來(lái)選擇

  • 選擇口碑較好的,比如 GitHub 星數(shù)、使用者數(shù)量質(zhì)量和使用者反饋

  • 開(kāi)源的優(yōu)先,往往項(xiàng)目有特殊需求可能需要改動(dòng)源代碼

按照上述思路,推薦以下選擇:

  • 客戶端架構(gòu):ShardingJDBC

  • 代理架構(gòu):MyCat 或 Atlas

兼容 MySQL 且可水平擴(kuò)展的數(shù)據(jù)庫(kù)

目前也有一些開(kāi)源數(shù)據(jù)庫(kù)兼容 MySQL 協(xié)議,如:

  1. https://github.com/pingcap/tidb

  2. http://www.cubrid.org/

但其工業(yè)品質(zhì)和 MySQL 尚有差距,且需要較大的運(yùn)維投入,如果想將原始的 MySQL 遷移到可水平擴(kuò)展的新數(shù)據(jù)庫(kù)中,可以考慮一些云數(shù)據(jù)庫(kù):

  1. https://cn.aliyun.com/product/petadata/?spm=5176.7960203.237031.38.cAzx5r

  2. https://cn.aliyun.com/product/oceanbase?spm=5176.7960203.237031.40.cAzx5r

  3. https://www.qcloud.com/product/dcdbfortdsql.html

NoSQL

在 MySQL 上做 Sharding 是一種戴著鐐銬的跳舞,事實(shí)上很多大表本身對(duì) MySQL 這種
RDBMS 的需求并不大,并不要求 ACID,可以考慮將這些表遷移到 NoSQL,徹底解決水平擴(kuò)展問(wèn)題,例如:

  • 日志類(lèi)、監(jiān)控類(lèi)、統(tǒng)計(jì)類(lèi)數(shù)據(jù)

  • 非結(jié)構(gòu)化或弱結(jié)構(gòu)化數(shù)據(jù)

  • 對(duì)事務(wù)要求不強(qiáng),且無(wú)太多關(guān)聯(lián)操作的數(shù)據(jù)

審核編輯 :李倩


聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 數(shù)據(jù)庫(kù)
    +關(guān)注

    關(guān)注

    7

    文章

    4033

    瀏覽量

    68412
  • MySQL
    +關(guān)注

    關(guān)注

    1

    文章

    914

    瀏覽量

    29626

原文標(biāo)題:誰(shuí)還說(shuō)不懂MySQL常用優(yōu)化,我就把這個(gè)丟過(guò)去!

文章出處:【微信號(hào):浩道linux,微信公眾號(hào):浩道linux】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    風(fēng)華功率電感的飽和電流與溫升電流有什么區(qū)別?

    材料進(jìn)入磁飽和狀態(tài)時(shí)所能承受的最大電流。當(dāng)電流超過(guò)該值時(shí),磁芯的磁通密度達(dá)到極限,進(jìn)一步增加電流不會(huì)顯著提升磁場(chǎng)強(qiáng)度,導(dǎo)致電感值急劇下降(通常定義為電感值衰減10%-30%時(shí)的電流)。此時(shí)電感性能惡化,可能引發(fā)電路輸出電壓波動(dòng)或
    的頭像 發(fā)表于 02-06 14:37 ?380次閱讀

    MOSFET相關(guān)問(wèn)題分享

    損壞。其次是功率。如果功率高于25%,MOS發(fā)熱嚴(yán)重,性能會(huì)急劇下降,因此在設(shè)計(jì)時(shí)需要對(duì)MOS進(jìn)行降額使用。 2.Q: 目前的MOSFET提供哪些封裝? A:封裝有TO-220、TO-220F
    發(fā)表于 01-26 07:46

    淘寶、京東、拼多多API大比拼,誰(shuí)才是電商運(yùn)營(yíng)的最佳拍檔?

    效率、文檔質(zhì)量、生態(tài)支持 等多個(gè)維度進(jìn)行深度對(duì)比,助您找到最適合業(yè)務(wù)需求的“技術(shù)拍檔”。 一、 接口覆蓋廣度:誰(shuí)的功能最全面? 淘寶/天貓API: 作為最早布局開(kāi)放生態(tài)的平臺(tái)之一,其API體系最為龐大和成熟。覆蓋商品管理(增刪改
    的頭像 發(fā)表于 12-16 14:34 ?468次閱讀
    淘寶、京東、拼多多API大比拼,誰(shuí)才是電商運(yùn)營(yíng)的最佳拍檔?

    在并聯(lián)使用MOS存在一些問(wèn)題,要怎樣做才能避免這些問(wèn)題?

    在并聯(lián)使用MOS存在一些問(wèn)題,那我們要怎樣做才能避免這些問(wèn)題? 首先,器件的一致性一定要好。 在功率MOSFET多管并聯(lián)時(shí),器件內(nèi)部參數(shù)的微小差異就會(huì)引起并聯(lián)各支路電流的不平衡而導(dǎo)致管過(guò)流損壞。 其次是功率。如果功率高于25%,MOS發(fā)熱嚴(yán)重,性能會(huì)
    發(fā)表于 12-10 08:19

    如何預(yù)防射頻模塊的性能下降

    預(yù)防射頻模塊(用于干擾發(fā)生類(lèi)儀器,如射頻信號(hào)發(fā)生器)性能下降,需圍繞其核心失效誘因(散熱不良、環(huán)境侵蝕、操作不當(dāng)、部件老化、負(fù)載異常),從 “環(huán)境控制、規(guī)范操作、定期維護(hù)、硬件保護(hù)、校準(zhǔn)溯源” 五大維度建立全生命周期預(yù)防體系,延緩部件老化、避免不可逆損傷。
    的頭像 發(fā)表于 10-18 10:46 ?887次閱讀

    光纖通訊問(wèn)題系統(tǒng)解決方案

    解決方案,涵蓋故障排查、優(yōu)化設(shè)計(jì)及維護(hù)策略: 一、信號(hào)衰減過(guò)大:光功率不足導(dǎo)致斷連或誤碼 問(wèn)題表現(xiàn) 光模塊接收端顯示“光功率過(guò)低”(RX Power 鏈路頻繁斷連或誤碼率(BER)升高。 短距離傳輸正常,長(zhǎng)距離后信號(hào)急劇下降。 解
    的頭像 發(fā)表于 09-09 10:27 ?1214次閱讀

    MySQL 8.0性能優(yōu)化實(shí)戰(zhàn)指南

    作為一名運(yùn)維工程師,MySQL數(shù)據(jù)庫(kù)優(yōu)化是我們?nèi)粘9ぷ髦凶罹咛魬?zhàn)性的任務(wù)之一。MySQL 8.0作為當(dāng)前主流版本,在性能、安全性和功能上都有了顯著提升,但如何充分發(fā)揮其潛力,仍需要我們掌握正確的優(yōu)化策略。
    的頭像 發(fā)表于 07-24 11:48 ?894次閱讀

    CAN總線電容過(guò)大?三種解決方案來(lái)了

    在新能源汽車(chē)路試中,CAN總線傳輸異常是一個(gè)常見(jiàn)問(wèn)題。本期我們將探討由于總線電容過(guò)大導(dǎo)致的下降沿過(guò)緩問(wèn)題,并介紹三種有效的解決方案。CAN總線下降沿過(guò)緩問(wèn)題新能源路試工程師在分析CAN總線波形
    的頭像 發(fā)表于 07-22 11:36 ?757次閱讀
    CAN總線電容<b class='flag-5'>過(guò)大</b>?三種解決方案來(lái)了

    MySQL數(shù)據(jù)庫(kù)是什么

    MySQL數(shù)據(jù)庫(kù)是一種 開(kāi)源的關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng)(RDBMS) ,由瑞典MySQL AB公司開(kāi)發(fā),后被Oracle公司收購(gòu)。它通過(guò)結(jié)構(gòu)化查詢語(yǔ)言(SQL)進(jìn)行數(shù)據(jù)存儲(chǔ)、管理和操作,廣泛應(yīng)用于Web
    的頭像 發(fā)表于 05-23 09:18 ?1269次閱讀

    HarmonyOS5云服務(wù)技術(shù)分享--云數(shù)據(jù)庫(kù)使用指南

    接觸HarmonyOS開(kāi)發(fā),還是想優(yōu)化現(xiàn)有的數(shù)據(jù)管理邏輯,這篇指南都會(huì)手把手帶你玩轉(zhuǎn)數(shù)據(jù)的增刪改,還有那些超實(shí)用的高級(jí)查詢功能! ? ??核心功能與使用場(chǎng)景?? 華為云數(shù)據(jù)庫(kù)(CloudDB)提供了
    發(fā)表于 05-22 18:29

    除了增刪改你對(duì)MySQL還了解多少

    我們都知道MySQL服務(wù)器的默認(rèn)端口為3306,之后就在這個(gè)端口號(hào)上等待客戶端進(jìn)程進(jìn)行連接(MySQL服務(wù)器會(huì)默認(rèn)監(jiān)聽(tīng)3306端口)。
    的頭像 發(fā)表于 04-14 17:20 ?768次閱讀

    鐵路安全守護(hù)者:北斗巡檢記錄儀的實(shí)戰(zhàn)應(yīng)用與成效

    在鐵路安全守護(hù)的征程中,北斗巡檢記錄儀宛如一位忠誠(chéng)的衛(wèi)士,憑借高精度定位、實(shí)時(shí)監(jiān)測(cè)預(yù)警、高效數(shù)據(jù)傳輸與智能分析等功能,在鐵路巡檢實(shí)戰(zhàn)中大顯身手,顯著提升了巡檢效率、降低了事故發(fā)生率,為鐵路安全筑牢
    的頭像 發(fā)表于 04-10 12:01 ?675次閱讀
    鐵路安全守護(hù)者:<b class='flag-5'>單</b>北斗巡檢<b class='flag-5'>記錄</b>儀的實(shí)戰(zhàn)應(yīng)用與成效

    云翎智能北斗執(zhí)法記錄儀的AI智能識(shí)別與云端協(xié)同解決方案

    在智慧執(zhí)法領(lǐng)域,云翎智能北斗執(zhí)法記錄儀以AI智能識(shí)別技術(shù)賦能,結(jié)合北斗高精度定位與云端協(xié)同分析,實(shí)現(xiàn)設(shè)備缺陷秒級(jí)預(yù)警、巡檢軌跡全程可視,使異常響應(yīng)效率提升60%,為行業(yè)數(shù)字化管理提供“精準(zhǔn)感知
    的頭像 發(fā)表于 04-08 11:35 ?1024次閱讀
    云翎智能<b class='flag-5'>單</b>北斗執(zhí)法<b class='flag-5'>記錄</b>儀的AI智能識(shí)別與云端協(xié)同解決方案

    零風(fēng)險(xiǎn):云翎智能北斗記錄儀如何助力巡檢數(shù)據(jù)成為法律鐵證?

    在巡檢工作日益復(fù)雜、法律證據(jù)要求愈發(fā)嚴(yán)苛的當(dāng)下,云翎智能北斗記錄儀憑借其100%國(guó)產(chǎn)化北斗芯片與數(shù)據(jù)加密傳輸技術(shù),徹底規(guī)避GPS泄密風(fēng)險(xiǎn),實(shí)現(xiàn)從硬件到軟件的全鏈路自主可控。云翎智能北斗記錄
    的頭像 發(fā)表于 04-07 11:47 ?804次閱讀
    零風(fēng)險(xiǎn):云翎智能<b class='flag-5'>單</b>北斗<b class='flag-5'>記錄</b>儀如何助力巡檢數(shù)據(jù)成為法律鐵證?

    從人工記錄到智能巡檢:云翎智能北斗記錄儀如何重塑電力巡檢

    從人工記錄到智能巡檢,云翎智能北斗記錄儀以其高精度定位、實(shí)時(shí)數(shù)據(jù)傳輸與智能管理能力,徹底重塑了電力設(shè)施的檢查流程。通過(guò)北斗衛(wèi)星導(dǎo)航系統(tǒng)的核心技術(shù)優(yōu)勢(shì),云翎智能北斗
    的頭像 發(fā)表于 04-03 14:58 ?872次閱讀
    從人工<b class='flag-5'>記錄</b>到智能巡檢:云翎智能<b class='flag-5'>單</b>北斗<b class='flag-5'>記錄</b>儀如何重塑電力巡檢