国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

老司機(jī)也該掌握的MySQL優(yōu)化指南

數(shù)據(jù)庫(kù) MySQL
當(dāng)MySQL單表記錄數(shù)過(guò)大時(shí),增刪改查性能都會(huì)急劇下降,所以我們本文會(huì)提供一些優(yōu)化參考,大家可以參考以下步驟來(lái)優(yōu)化。

老司機(jī)也該掌握的MySQL優(yōu)化指南

當(dāng)MySQL單表記錄數(shù)過(guò)大時(shí),增刪改查性能都會(huì)急劇下降,所以我們本文會(huì)提供一些優(yōu)化參考,大家可以參考以下步驟來(lái)優(yōu)化:

一、單表優(yōu)化

除非單表數(shù)據(jù)未來(lái)會(huì)一直不斷上漲,否則不要一開(kāi)始就考慮拆分,拆分會(huì)帶來(lái)邏輯、部署、運(yùn)維的各種復(fù)雜度。一般以整型值為主的表在***以下,字符串為主的表在五百萬(wàn)以下是沒(méi)有太大問(wèn)題的,而事實(shí)上很多時(shí)候MySQL單表的性能依然有不少優(yōu)化空間,甚至能正常支撐***以上的數(shù)據(jù)量。

1.字段

  •  盡量使用TINYINT、SMALLINT、MEDIUM_INT作為整數(shù)類(lèi)型而非INT,如果非負(fù)則加上UNSIGNED;
  •  VARCHAR的長(zhǎng)度只分配真正需要的空間;
  •  使用枚舉或整數(shù)代替字符串類(lèi)型;
  •  盡量使用TIMESTAMP而非DATETIME;
  •  單表不要有太多字段,建議在20以?xún)?nèi);
  •  避免使用字段,很難查詢(xún)優(yōu)化且占用額外索引空間;
  •  用整型來(lái)存IP。

2.索引

  •  索引并不是越多越好,要根據(jù)查詢(xún)有針對(duì)性的創(chuàng)建,考慮在WHERE和ORDER BY命令上涉及的列建立索引,可根據(jù)EXPLAIN來(lái)查看是否用了索引還是全表掃描;
  •  應(yīng)盡量避免在WHERE子句中對(duì)字段進(jìn)行值判斷,否則將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描;
  •  值分布很***的字段不適合建索引,例如“性別”這種只有兩三個(gè)值的字段;
  •  字符字段只建前綴索引;
  •  字符字段***不要做主鍵;
  •  不用外鍵,由程序保證約束;
  •  盡量不用UNIQUE,由程序保證約束;
  •  使用多列索引時(shí)主意順序和查詢(xún)條件保持一致,同時(shí)刪除不必要的單列索引。

3.查詢(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ù)量也不要太大。

4.引擎

目前廣泛使用的是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ù);
  •  不支持全文索引。

ps: 據(jù)說(shuō)InnoDB已經(jīng)在MySQL 5.6.4支持全文索引了

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

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

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

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

    https://github.com/akopytov/sysbench

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

    https://github.com/tmcallaghan/iibench-mysql

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

    https://github.com/Percona-Lab/tpcc-mysql

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

  •  back_log:back_log值可以指出在MySQL暫時(shí)停止回答新請(qǐng)求之前的短時(shí)間內(nèi)多少個(gè)請(qǐng)求可以被存在堆棧中。也就是說(shuō),如果MySQL的連接數(shù)據(jù)達(dá)到max_connections時(shí),新來(lái)的請(qǐng)求將會(huì)被存在堆棧中,以等待某一連接釋放資源,該堆棧的數(shù)量即back_log,如果等待連接的數(shù)量超過(guò)back_log,將不被授予連接資源。可以從默認(rèn)的50升至500。
  •  wait_timeout:數(shù)據(jù)庫(kù)連接閑置時(shí)間,閑置連接會(huì)占用內(nèi)存資源。可以從默認(rèn)的8小時(shí)減到半小時(shí)。
  •  max_user_connection:***連接數(shù),默認(rèn)為0無(wú)上限,***設(shè)一個(gè)合理上限。
  •  thread_concurrency:并發(fā)線(xiàn)程數(shù),設(shè)為CPU核數(shù)的兩倍。
  •  skip_name_resolve:禁止對(duì)外部連接進(jìn)行DNS解析,消除DNS解析時(shí)間,但需要所有遠(yuǎn)程主機(jī)用IP訪(fǎng)問(wèn)。
  •  key_buffer_size:索引塊的緩存大小,增加會(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%以下***。
  •  innodb_buffer_pool_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越高越好。
  •  innodb_additional_mem_pool_size: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)存中提高訪(fǎng)問(wèn)效率,當(dāng)過(guò)小的時(shí)候,MySQL會(huì)記錄Warning信息到數(shù)據(jù)庫(kù)的錯(cuò)誤日志中,這時(shí)就需要該調(diào)整這個(gè)參數(shù)大小。
  •  innodb_log_buffer_size:InnoDB存儲(chǔ)引擎的事務(wù)日志所使用的緩沖區(qū),一般來(lái)說(shuō)不建議超過(guò)32MB。
  •  query_cache_size:緩存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可能得不償失。根據(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使用大小。
  •  read_buffer_size:MySQL讀入緩沖區(qū)大小。對(duì)表進(jìn)行順序掃描的請(qǐng)求將分配一個(gè)讀入緩沖區(qū),MySQL會(huì)為它分配一段內(nèi)存緩沖區(qū)。如果對(duì)表的順序掃描請(qǐng)求非常頻繁,可以通過(guò)增加該變量值以及內(nèi)存緩沖區(qū)大小提高其性能。
  •  sort_buffer_size:MySQL執(zhí)行排序使用的緩沖大小。如果想要增加ORDER BY的速度,首先看是否可以讓MySQL使用索引而不是額外的排序階段。如果不能,可以嘗試增加sort_buffer_size變量的大小。
  •  read_rnd_buffer_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è)順序掃描的線(xiàn)程為其掃描的每張表分配這個(gè)大小的一個(gè)緩沖區(qū)。如果你做很多順序掃描,可能想要增加該值。
  •  thread_cache_size:保存當(dāng)前沒(méi)有與連接關(guān)聯(lián)但是準(zhǔn)備為后面新的連接服務(wù)的線(xiàn)程,可以快速響應(yīng)連接的線(xiàn)程請(qǐng)求而無(wú)需創(chuàng)建新的。
  •  table_cache:類(lèi)似于thread_cache _size,但用來(lái)緩存表文件,對(duì)InnoDB效果不大,主要用于MyISAM。

6.升級(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ù)訪(fǎng)問(wèn)層:比如MyBatis針對(duì)SQL語(yǔ)句做緩存,而Hibernate可以精確到單個(gè)記錄,這里緩存的對(duì)象主要是持久化對(duì)象Persistence Object;
  •  應(yīng)用服務(wù)層:可以通過(guò)編程手段對(duì)緩存做到更精準(zhǔn)的控制和更多的實(shí)現(xiàn)策略,這里緩存的對(duì)象是數(shù)據(jù)傳輸對(duì)象Data Transfer Object;
  •  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)有全局索引。

用戶(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ū)上: 

  1. mysql> explain partitions select count(1) from user_partition where id in (1,2,3,4,5);  
  2. +----+-------------+----------------+------------+-------+---------------+---------+---------+------+------+--------------------------+  
  3. | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | Extra |  
  4. | 1 | SIMPLE | user_partition | p1,p4 | range | PRIMARY | PRIMARY | 8 | | 5 | Using where; Using index |  
  5. 1 row in set (0.00 sec) 

分區(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è)索引的互斥訪(fǎng)問(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ú)法使用外鍵約束;
  •  值會(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ū),如下所示: 
  1. CREATE TABLE members (  
  2. firstname VARCHAR(25) NOT ,  
  3. lastname VARCHAR(25) NOT ,  
  4. username VARCHAR(16) NOT ,  
  5. email VARCHAR(35),  
  6. joined DATE NOT  
  7. )PARTITION BY RANGE( YEAR(joined) ) (  
  8. PARTITION p0 VALUES LESS THAN (1960),  
  9. PARTITION p1 VALUES LESS THAN (1970),  
  10. PARTITION p2 VALUES LESS THAN (1980),  
  11. PARTITION p3 VALUES LESS THAN (1990),  
  12. PARTITION p4 VALUES LESS THAN MAXVALUE  
  13. ); 

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

  •  如果數(shù)據(jù)有明顯的熱點(diǎn),而且除了這部分?jǐn)?shù)據(jù),其他數(shù)據(jù)很少被訪(fǎng)問(wèn)到,那么可以將熱點(diǎn)數(shù)據(jù)單獨(dú)放在一個(gè)分區(qū),讓這個(gè)分區(qū)的數(shù)據(jù)能夠有機(jī)會(huì)都緩存在內(nèi)存中,查詢(xún)時(shí)只訪(fǎng)問(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ù)表是:

垂直拆分后是:

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

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

六、水平拆分

1.概述

水平拆分是通過(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é)果是:

實(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ù)量極大。

2.分片原則

  •  能不分就不分,參考單表優(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ù)的訪(fǎng)問(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)椴粠魏蜽here語(yǔ)句的查詢(xún)SQL,會(huì)遍歷所有的分片,性能相對(duì)最差,因此這種SQL越多,對(duì)系統(tǒng)的影響越大,所以我們要盡量避免這種SQL的產(chǎn)生。

3.解決方案

由于水平拆分牽涉的邏輯比較復(fù)雜,當(dāng)前也有了不少比較成熟的解決方案。這些方案分為兩大類(lèi):客戶(hù)端架構(gòu)和代理架構(gòu)。

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

通過(guò)修改數(shù)據(jù)訪(fǎng)問(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)的例子:

可以看到分片的實(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ù)訪(fǎng)問(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)的例子:

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

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

  •  能夠處理非常復(fù)雜的需求,不受數(shù)據(jù)庫(kù)訪(fǎng)問(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)。

目前來(lái)說(shuō),業(yè)界還是有很多的方案可供選擇,但應(yīng)該如何進(jìn)行選擇?我認(rè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)源代碼。 
責(zé)任編輯:龐桂玉 來(lái)源: 今日頭條
相關(guān)推薦

2018-10-09 09:42:27

MySQL優(yōu)化單表

2018-11-28 09:38:34

微服務(wù)架構(gòu)API

2021-01-22 13:54:26

運(yùn)維架構(gòu)技術(shù)

2018-03-09 10:34:48

顯卡參數(shù)超頻

2017-09-19 09:19:16

程序員開(kāi)發(fā)方向

2018-10-26 09:22:57

微服務(wù)架構(gòu)應(yīng)用開(kāi)發(fā)

2017-10-18 13:28:27

語(yǔ)言Python開(kāi)發(fā)錯(cuò)誤

2018-06-13 09:45:11

人工智能

2018-03-07 10:50:46

MySQL分布式存儲(chǔ)

2020-11-23 11:40:35

MySQSQL數(shù)據(jù)庫(kù)

2017-09-20 09:06:20

程序員網(wǎng)站后端服務(wù)

2024-06-04 09:48:14

自動(dòng)駕駛模型

2020-11-09 14:15:23

代碼菜鳥(niǎo)老司機(jī)

2017-05-24 10:58:28

linux系統(tǒng)技巧

2016-05-12 15:34:04

云計(jì)算

2019-07-18 14:17:25

運(yùn)維命令網(wǎng)絡(luò)

2018-02-06 09:47:32

windows系統(tǒng)優(yōu)化系統(tǒng)卡頓

2019-11-04 11:50:35

人工智能機(jī)器學(xué)習(xí)技術(shù)

2021-04-09 09:51:52

CyclicBarri Java循環(huán)柵欄

2020-03-09 10:21:12

Java集合類(lèi) Guava
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

久久aⅴ国产欧美74aaa| 粉嫩虎白女毛片人体| 97超碰色婷婷| 日韩成人网免费视频| 欧美日韩一二三四五区| 久久久不卡影院| 免费日本视频一区| 天天影视欧美综合在线观看| 久久久久久久久成人| h片在线免费| 中文字幕一区二区三区域| 男人日女人视频网站| 欧美日韩一区二| 国产主播精品在线| 久久乐国产精品| 在线亚洲男人天堂| 日韩女优av电影在线观看| 精品国产91乱高清在线观看| 欧美国产亚洲另类动漫| 国产成人免费视频网站高清观看视频| 中文国产一区| 亚洲国产一成人久久精品| 综合伊思人在钱三区| 一本色道69色精品综合久久| 免费亚洲电影| 不卡的av影片| 国产在线观看91| 日本大臀精品| 国产在线传媒| 黄a免费视频| 亚洲少妇第一页| 国产美女网站在线观看| 韩国黄色一级大片| 欧美日韩一区二区三区在线视频| 91网站免费看| 国产精品视频男人的天堂| 69久久夜色精品国产69| 欧美国产日韩精品| 精品国产一区二区三区久久久| 国产婷婷成人久久av免费高清| 欧美精品aⅴ在线视频| 日本高清不卡aⅴ免费网站| 亚洲成人av免费| 亚洲另类中文字| 18欧美乱大交hd1984| 中文字幕国产精品一区二区| 制服丝袜中文字幕在线| 精产国产伦理一二三区| 天堂在线亚洲| 缴情综合网五月天| 成人免费在线观看视频网站| 男人天堂999| 97av视频在线观看| 成 年 人 黄 色 大 片大 全| a级黄色片免费| 精品一区二区三区无码视频| 男插女免费视频| 日韩最新中文字幕| www国产免费| 大陆av在线播放| 久久国产精品网| 日本韩国欧美在线观看| 免费成人在线视频网站| www.四虎成人| 99热在线观看免费| 8x8x8x视频在线观看| 日本xxxx高清色视频| 3d黄动漫网站| 超碰在线电影| 亚洲成人影院在线观看| 毛片免费在线| 免费网站黄在线观看| 青青草原国产在线| 欧美人体一区二区三区| 四虎视频在线精品免费网址| 日韩区欧美区| 蜜桃国内精品久久久久软件9| 伊人久久大香线蕉综合网蜜芽| 成人情趣视频网站| 欧美日韩精品免费观看视频完整| 亚洲一区自拍| 韩国欧美一区二区| 久久色成人在线| 亚洲欧美日韩国产一区二区三区 | 欧美一区二区三区四区五区六区| 欧美日韩一区二区三区免费| 亚洲欧美日韩精品久久久| 妞干网视频在线观看| 天天影视综合色| 一级片在线视频| 黄视频在线观看网站| 视频二区不卡| 美国一区二区| 国产综合自拍| 九九久久精品视频| 久久综合九色综合欧美亚洲| 一区二区三区四区蜜桃| 欧美日韩一区中文字幕| 亚洲欧美国产精品专区久久| 欧美激情免费在线| 国产一区视频在线| 日本一区二区三区视频免费看| 日本福利视频一区| 日本免费专区| caoporm免费视频在线| 成人在线不卡| 日韩免费一区| 久久精品国产亚洲高清剧情介绍 | 精品视频色一区| 日韩国产在线看| 久久伊人精品天天| 欧洲亚洲免费在线| 99精品美女| 97在线观看视频| 国产精品亚洲二区| 中文字幕亚洲二区| 91桃色在线| 亚洲国产日韩一区| 女子免费在线观看视频www| 亚洲一区二区欧美日韩| 一级黄色在线| 亚洲精品网址在线观看| 欧美激情乱人伦| 国产91精品一区二区绿帽| 香蕉视频免费版| 黄色av资源| 91九色美女在线视频| 啪啪激情综合网| 久久久久久久欧美精品| 国产欧美日本一区二区三区| 欧美优质美女网站| 久久精品久久久久久国产 免费| 国产精品色视频| 国产奶头好大揉着好爽视频| 初尝黑人巨炮波多野结衣电影| 人人超在线公开视频| 日韩一级电影| 青青草精品视频| 亚洲精选视频在线| 亚洲精品动漫久久久久| 国产精品久久不能| 激情视频小说图片| 在线看国产视频| 91天天综合| 红桃视频欧美| 欧美经典一区二区三区| 日韩欧美在线网站| 国产ts人妖一区二区三区| 在线一区高清| 在线视频您懂的| 日韩大陆av| 99热免费精品| 亚洲欧美日本在线| 亚洲美女av网站| 97人人干人人| 国产福利影院在线观看| 人人澡人人添人人爽一区二区| 99久久久无码国产精品6| 黄页网站大全在线观看| 岛国视频免费在线观看| 久久影院一区二区三区| 久久婷婷激情| 亚洲大片精品永久免费| 久久亚洲一区二区三区四区五区高| 久久伦理网站| h网址在线观看| 日本午夜免费一区二区| 男女精品网站| 午夜精品福利在线| 久久99亚洲精品| 一本一道久久久a久久久精品91| 污视频在线看操| av成人综合| 国产a视频精品免费观看| 欧美日韩国产高清一区二区三区 | www.日本在线播放| 免费在线观看av网站| 国产成人久久| 久久影院电视剧免费观看| 亚洲国产毛片完整版| 国产精品久久波多野结衣| 国产日本韩国在线播放| 未满十八勿进黄网站一区不卡| 日韩国产在线观看一区| 一本久久a久久精品亚洲| 欧美一区二区三区免费视| 欧美激情 国产精品| 电影在线观看一区| 一区二区日本视频| 狠狠操狠狠色综合网| 欧美在线视频免费| 国产成人精品视频免费看| 欧洲一区精品| 97成人超碰| 国产午夜久久av| 粉嫩aⅴ一区二区三区四区| 亚洲国产精品网站| 日本不卡二区高清三区| jzzjzzjzz亚洲成熟少妇| 99久久久久|