在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

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 以?xún)?nèi)

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

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

索引

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

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

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

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

  • 字符字段只建前綴索引

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

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

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

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

查詢(xún)SQL

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

  • 不做列運(yùn)算:SELECT id WHERE age+1=10,任何對(duì)列的操作都將導(dǎo)致表掃描,它包括數(shù)據(jù)庫(kù)教程函數(shù)、計(jì)算表達(dá)式等等,查詢(xún)時(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 以?xún)?nèi)

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

  • 避免 %xxx 式查詢(xún)

  • 少用 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ù)

  • 在表有讀取查詢(xún)的同時(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,將不被授予連接資源。可以從默認(rèn)的 50 升至 500

  • wait_timeout:數(shù)據(jù)庫(kù)連接閑置時(shí)間,閑置連接會(huì)占用內(nèi)存資源。可以從默認(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ò)查詢(xún)show status like'key_read%',保證 key_reads / key_read_requests 在 0.1% 以下最好

  • innodbbufferpool_size:緩存數(shù)據(jù)塊和索引塊,對(duì) InnoDB 表性能影響最大。通過(guò)查詢(xún)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é)果集,所以?xún)H僅只能針對(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)行排序查詢(xún)時(shí),MySql 會(huì)首先掃描一遍該緩沖,以避免磁盤(pán)搜索,提高查詢(xún)速度,如果需要排序大量數(shù)據(jù),可適當(dāng)調(diào)高該值。但 MySql 會(huì)為每個(gè)客戶(hù)連接發(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è)面做緩存

  • 瀏覽器客戶(hù)端:用戶(hù)端的緩存

可以根據(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)單的水平拆分,用戶(hù)需要在建表的時(shí)候加上分區(qū)參數(shù),對(duì)應(yīng)用是透明的無(wú)需修改代碼

對(duì)用戶(hù)來(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

用戶(hù)的 SQL 語(yǔ)句是需要針對(duì)分區(qū)表做優(yōu)化,SQL 條件中要帶上分區(qū)條件的列,從而使查詢(xún)定位到少量的分區(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ù)等操作

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

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

  • 可以使用分區(qū)表賴(lài)避免某些特殊瓶頸,例如 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ū):基于用戶(hù)定義的表達(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

查詢(xún)時(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)存中,查詢(xún)時(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ù)里面既存在用戶(hù)數(shù)據(jù),又存在訂單數(shù)據(jù),那么垂直拆分可以把用戶(hù)數(shù)據(jù)放到用戶(hù)庫(kù)、把訂單數(shù)據(jù)放到訂單庫(kù)。

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

比如原始的用戶(hù)表是:

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

垂直拆分后是:

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

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

  • 可以使得行數(shù)據(jù)變小,一個(gè)數(shù)據(jù)塊( Block )就能存放更多的數(shù)據(jù),在查詢(xún)時(shí)就會(huì)減少 I/O 次數(shù)(每次查詢(xún)時(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)解決

前面垂直拆分的用戶(hù)表如果進(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è)查詢(xún) 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)題

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

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

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

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

解決方案

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

  • 客戶(hù)端架構(gòu)

  • 代理架構(gòu)

客戶(hù)端架構(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è)客戶(hù)端架構(gòu)的例子:

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

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

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

  • 應(yīng)用直連數(shù)據(jù)庫(kù),降低外圍系統(tǒng)依賴(lài)所帶來(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ě)分離 外部依賴(lài) 是否開(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 阿里巴巴 客戶(hù)端架構(gòu) MySQL 無(wú) 無(wú) 無(wú) Java Java 344
TDDL 淘寶 客戶(hù)端架構(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) 客戶(hù)端架構(gòu) MySQL 無(wú) Java Java 1144
Shark 個(gè)人 客戶(hù)端架構(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 客戶(hù)端架構(gòu) MySQL 無(wú) 無(wú) Ruby Ruby 957
HibernateShard Hibernate 客戶(hù)端架構(gòu) 無(wú)限制 無(wú) 無(wú) Java Java 57
MybatisShard MakerSoft 客戶(hù)端架構(gòu) 無(wú)限制 無(wú) 無(wú) Java Java 119
Gizzard Twitter 代理架構(gòu) 無(wú)限制 無(wú) 無(wú) Java 無(wú)限制 2087


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

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

  • 具體功能是否滿(mǎn)足,比如需要跨節(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)源代碼

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

  • 客戶(hù)端架構(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

    文章

    3904

    瀏覽量

    65831
  • MySQL
    +關(guān)注

    關(guān)注

    1

    文章

    849

    瀏覽量

    27615

原文標(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)推薦

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

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

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

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

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

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

    數(shù)據(jù)庫(kù)數(shù)據(jù)恢復(fù)——MySQL數(shù)據(jù)庫(kù)誤刪除表記錄的數(shù)據(jù)恢復(fù)案例

    本地服務(wù)器,安裝的windows server操作系統(tǒng)。 操作系統(tǒng)上部署MySQL實(shí)例,引擎類(lèi)型為innodb,表空間類(lèi)型為獨(dú)立表空間。該MySQL數(shù)據(jù)庫(kù)沒(méi)有備份,未開(kāi)啟binlog。 人為
    的頭像 發(fā)表于 02-22 09:44 ?580次閱讀
    數(shù)據(jù)庫(kù)數(shù)據(jù)恢復(fù)——<b class='flag-5'>MySQL</b>數(shù)據(jù)庫(kù)誤刪除<b class='flag-5'>表記錄</b>的數(shù)據(jù)恢復(fù)案例

    功率因數(shù)過(guò)低引發(fā)的問(wèn)題及其影響

    ,包括能耗增加、設(shè)備壽命縮短、電網(wǎng)負(fù)荷加重、系統(tǒng)穩(wěn)定性下降等。本文將從技術(shù)角度深入剖析功率因數(shù)過(guò)低可能引發(fā)的各種問(wèn)題及其影響,以期為相關(guān)領(lǐng)域的從業(yè)人員提供有價(jià)值的參考。
    的頭像 發(fā)表于 02-02 14:41 ?1426次閱讀

    Flexus 云服務(wù) X 實(shí)例應(yīng)用,通過(guò) QT 連接華為云 MySQL,進(jìn)行數(shù)據(jù)庫(kù)的操作,數(shù)據(jù)表的增刪改

    引出 在華為云 828?B2B 企業(yè)節(jié)期間,F(xiàn)lexus?X 實(shí)例限時(shí)促銷(xiāo),性?xún)r(jià)比極高!對(duì)于需要高算力的企業(yè)用戶(hù)和開(kāi)發(fā)者,這款實(shí)例可以顯著提升自建 MySQL、Redis、Nginx 的運(yùn)行性能
    的頭像 發(fā)表于 01-23 17:23 ?320次閱讀
    Flexus 云服務(wù) X 實(shí)例應(yīng)用,通過(guò) QT 連接華為云 <b class='flag-5'>MySQL</b>,進(jìn)行數(shù)據(jù)庫(kù)的操作,數(shù)據(jù)表的<b class='flag-5'>增刪改</b><b class='flag-5'>查</b>

    頂堅(jiān)北斗防爆執(zhí)勤記錄儀在電力能源行業(yè)應(yīng)用的優(yōu)勢(shì)是什么?

    頂堅(jiān)北斗防爆執(zhí)勤記錄儀在電力能源行業(yè)展現(xiàn)出顯著優(yōu)勢(shì),憑借北斗衛(wèi)星導(dǎo)航系統(tǒng)的高精度定位能力,結(jié)合實(shí)時(shí)數(shù)據(jù)傳輸、高清視頻錄制與抓拍功能,以及出色的防爆與安全性能,為電力行業(yè)提供了高效、安全的作業(yè)支持
    的頭像 發(fā)表于 01-14 11:35 ?351次閱讀
    頂堅(jiān)<b class='flag-5'>單</b>北斗防爆執(zhí)勤<b class='flag-5'>記錄</b>儀在電力能源行業(yè)應(yīng)用的優(yōu)勢(shì)是什么?

    華為云 Flexus X 實(shí)例 MySQL 性能加速評(píng)測(cè)及對(duì)比

    基于 sysbench 構(gòu)造測(cè)試表和測(cè)試數(shù)據(jù) 12 3.5 數(shù)據(jù)庫(kù)讀寫(xiě)性能測(cè)試 13 四、業(yè)界 U?系列無(wú)加速 MySQL 測(cè)
    的頭像 發(fā)表于 12-25 17:10 ?506次閱讀
    華為云 Flexus X 實(shí)例 <b class='flag-5'>MySQL</b> <b class='flag-5'>性能</b>加速評(píng)測(cè)及對(duì)比

    數(shù)據(jù)庫(kù)數(shù)據(jù)恢復(fù)—Mysql數(shù)據(jù)庫(kù)表記錄丟失的數(shù)據(jù)恢復(fù)流程

    Mysql數(shù)據(jù)庫(kù)故障: Mysql數(shù)據(jù)庫(kù)表記錄丟失。 Mysql數(shù)據(jù)庫(kù)故障表現(xiàn): 1、Mysql數(shù)據(jù)庫(kù)表中無(wú)任何數(shù)據(jù)或只有部分?jǐn)?shù)據(jù)
    的頭像 發(fā)表于 12-16 11:05 ?539次閱讀
    數(shù)據(jù)庫(kù)數(shù)據(jù)恢復(fù)—<b class='flag-5'>Mysql</b>數(shù)據(jù)庫(kù)<b class='flag-5'>表記錄</b>丟失的數(shù)據(jù)恢復(fù)流程

    tlv320aic3101怎樣才能在使用AGC效果的同時(shí),保證SINAD參數(shù)的良好?

    mVRMS 時(shí),輸出信號(hào)出現(xiàn)削峰,此時(shí)SINAD急劇下降。 (2)芯片的總增益為一定值K,通過(guò)對(duì)寄存器進(jìn)行設(shè)置,將最終輸出恒定設(shè)置為630 mVRMS 當(dāng)輸出隨輸入的增加,第一次到達(dá)630 mVRMS
    發(fā)表于 11-06 06:51

    電源軌的封裝電感過(guò)大怎么辦

    當(dāng)電源軌的封裝電感過(guò)大時(shí),可能會(huì)對(duì)電路的性能和穩(wěn)定性產(chǎn)生不利影響,如增加能量損耗、降低效率、增加噪聲等。針對(duì)這一問(wèn)題,可以采取以下幾種方法來(lái)解決:
    的頭像 發(fā)表于 10-01 15:32 ?592次閱讀

    記錄到管理:北斗工作記錄儀如何優(yōu)化工作流程

    在這個(gè)快節(jié)奏的時(shí)代,每一分效率的提升都是企業(yè)競(jìng)爭(zhēng)力的關(guān)鍵。從繁瑣的手工記錄到智能化的數(shù)據(jù)管理,技術(shù)的飛躍正悄然改變著我們的工作方式。頂堅(jiān)北斗工作記錄儀如何成為優(yōu)化工作流程的得力助手,實(shí)現(xiàn)從
    的頭像 發(fā)表于 08-30 11:09 ?483次閱讀
    從<b class='flag-5'>記錄</b>到管理:<b class='flag-5'>單</b>北斗工作<b class='flag-5'>記錄</b>儀如何優(yōu)化工作流程

    磁路飽和對(duì)磁路的等效電感有何影響

    。磁路飽和通常發(fā)生在磁路中磁通密度較高的區(qū)域,如磁芯、磁環(huán)等。 磁路飽和的原因主要有以下幾點(diǎn): 1.1 材料特性:不同的磁性材料具有不同的飽和磁通密度,當(dāng)磁通密度超過(guò)材料的飽和磁通密度時(shí),磁導(dǎo)率會(huì)急劇下降,導(dǎo)致磁路飽
    的頭像 發(fā)表于 08-29 15:20 ?2416次閱讀

    精準(zhǔn)記錄,高效分析:北斗現(xiàn)場(chǎng)記錄儀在各行各業(yè)的應(yīng)用

    在這個(gè)信息爆炸、效率至上的時(shí)代,每一個(gè)細(xì)節(jié)的記錄與分析都成為了推動(dòng)行業(yè)進(jìn)步的關(guān)鍵力量。北斗現(xiàn)場(chǎng)記錄儀,作為集高精度定位、高清視頻錄制、智能數(shù)據(jù)分析于一體的創(chuàng)新設(shè)備,正悄然改變著各行各業(yè)的作業(yè)模式
    的頭像 發(fā)表于 08-28 11:46 ?653次閱讀
    精準(zhǔn)<b class='flag-5'>記錄</b>,高效分析:<b class='flag-5'>單</b>北斗現(xiàn)場(chǎng)<b class='flag-5'>記錄</b>儀在各行各業(yè)的應(yīng)用

    索尼日本裁員應(yīng)對(duì)光盤(pán)需求下滑

    近日,索尼公司宣布將在其位于日本東北部的可記錄媒體制造廠進(jìn)行大規(guī)模裁員,共計(jì)250名員工將受到影響。此次裁員的主要原因是隨著流媒體服務(wù)的日益普及,消費(fèi)者對(duì)傳統(tǒng)光盤(pán)媒體的需求急劇下降,導(dǎo)致市場(chǎng)銷(xiāo)量萎縮。
    的頭像 發(fā)表于 07-02 16:07 ?1523次閱讀
    主站蜘蛛池模板: 加勒比综合网 | 久草资源在线播放 | 免费观看色视频 | 成在线人永久免费播放视频 | 人人草在线 | 夜色爽 | 四虎影视免费看 | 亚洲精品午夜久久aaa级久久久 | 91大神精品长腿在线观看网站 | 色综合激情网 | 色婷婷综合久久久久中文一区二区 | 最近国语剧情视频在线观看 | 视频在线免费观看网址 | 免费看欧美一级片 | 国产福利午夜自产拍视频在线 | 欧美综合色 | 中文字幕一精品亚洲无线一区 | 国产成人综合网 | 伊人久久综合网亚洲 | 亚洲va久久久噜噜噜久久狠狠 | 站长工具天天爽视频 | 亚洲一区二区三区电影 | 国产日韩欧美一区二区 | 天天干天天操天天舔 | 巨臀中文字幕一区二区翘臀 | 福利社藏经阁 | 国产成人精品高清在线 | 亚欧乱色束缚一区二区三区 | 国产一区二区中文字幕 | 老师在办公室被躁得舒服小说 | 天堂网在线播放 | 午夜免费视频福利集合100 | 精品伊人久久大线蕉色首页 | 久久精品国产免费看久久精品 | 一级片在线观看视频 | 欧美人与zoxxxx视频 | 天天碰夜夜操 | 四虎影院国产 | 色视频2| 躁天天躁中文字幕在线 | 97干97吻|