真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

mysql表分區(qū)怎么優(yōu)化 mysql 表分區(qū)性能提升不大

怎么樣優(yōu)化MySQL分區(qū)表

1、分表,即把一個很大的表達數(shù)據(jù)分到幾個表中,這樣每個表數(shù)據(jù)都不多。

創(chuàng)新互聯(lián)公司專注于海晏企業(yè)網(wǎng)站建設(shè),成都響應(yīng)式網(wǎng)站建設(shè)公司,商城網(wǎng)站制作。海晏網(wǎng)站建設(shè)公司,為海晏等地區(qū)提供建站服務(wù)。全流程按需求定制制作,專業(yè)設(shè)計,全程項目跟蹤,創(chuàng)新互聯(lián)公司專業(yè)和態(tài)度為您提供的服務(wù)

優(yōu)點:提高并發(fā)量,減小鎖的粒度

缺點:代碼維護成本高,相關(guān)sql都需要改動

2、分區(qū),所有的數(shù)據(jù)還在一個表中,但物理存儲數(shù)據(jù)根據(jù)一定的規(guī)則存放在不同的文件中,文件也可以放到另外磁盤上

優(yōu)點:代碼維護量小,基本不用改動,提高IO吞吐量

缺點:表的并發(fā)程度沒有增加

3、拆分業(yè)務(wù),這個本質(zhì)還是分表。

優(yōu)點:長期支持更好

缺點:代碼邏輯重構(gòu),工作量很大

當(dāng)然,每種情況都有合適的應(yīng)用場景,需要根據(jù)具體業(yè)務(wù)具體選擇。由于分表和拆分業(yè)務(wù)和mysql本身關(guān)系不大屬于業(yè)務(wù)層面,我們只說和數(shù)據(jù)庫關(guān)系最緊密的方式:表分區(qū)。不過使用表分區(qū)有個前提就是你的數(shù)據(jù)庫必須支持。那么,怎么知道我的數(shù)據(jù)庫是否支持表分區(qū)呢

? 請執(zhí)行下面命令

mysql表分區(qū)使用及詳細介紹

一、分區(qū)概念

分區(qū)是將一個表分成多個區(qū)塊進行操作和保存,從而降低每次操作的數(shù)據(jù),提高性能。而對于應(yīng)用來說則是透明的,從邏輯上看只有一張表,但在物理上這個表可能是由多個物理分區(qū)組成的,每個分區(qū)都是獨立的對象,可以進行獨立處理。

二、分區(qū)作用

1.可以邏輯數(shù)據(jù)分割,分割數(shù)據(jù)能夠有多個不同的物理文件路徑。

2.可以存儲更多的數(shù)據(jù),突破系統(tǒng)單個文件最大限制。

3.提升性能,提高每個分區(qū)的讀寫速度,提高分區(qū)范圍查詢的速度。

4.可以通過刪除相關(guān)分區(qū)來快速刪除數(shù)據(jù)

5.通過跨多個磁盤來分散數(shù)據(jù)查詢,從而提高磁盤I/O的性能。

6.涉及到例如SUM()、COUNT()這樣聚合函數(shù)的查詢,可以很容易的進行并行處理。

7.可以備份和恢復(fù)獨立的分區(qū),這對大數(shù)據(jù)量很有好處。

三、分區(qū)能支持的引擎

MySQL支持大部分引擎創(chuàng)建分區(qū),入MyISAM、InnoDB等;不支持MERGE和CSV等來創(chuàng)建分區(qū)。同一個分區(qū)表中的所有分區(qū)必須是同一個存儲引擎。值得注意的是,在MySQL8版本中,MyISAM表引擎不支持分區(qū)。

四、確認MySQL支持分區(qū)

從MySQL5.1開始引入分區(qū)功能,可以如下方式查看是否支持:

老版本用:SHOW VARIABLES LIKE '%partition%';

新版本用:show plugins;

五、分區(qū)類型

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

例如,可以將一個表通過年份劃分成兩個分區(qū),2001 -2010年、2011-2020。

2. LIST分區(qū):類似于RANGE分區(qū),LIST是列值匹配一個離散值集合中的某個值來進行選擇。

比如 根據(jù)字段 把值為1、3、5的放到一起,2、4、6的另外放到一起 等等...

3. HASH分區(qū):基于用戶定義的表達式的返回值來進行選擇分區(qū),該表達式使用將要插入到表中的這些行的列值來進行計算,這個函數(shù)必須產(chǎn)生非負整數(shù)值。

通過HASH運算來進行分區(qū),分布的比較均勻

4. KEY分區(qū):類似于按HASH分區(qū),由MySQL服務(wù)器提供其自身的哈希函數(shù)。

按照KEY進行分區(qū)類似于按照HASH分區(qū)

六、分區(qū)創(chuàng)建注意事項

1. 如果表中存在primary key 或者 unique key 時,分區(qū)的列必須是paimary key或者unique key的一個組成部分,也就是說,分區(qū)函數(shù)的列只能從pk或者uk這些key中取子集

2. 如果表中不存在任何的paimary key或者unique key,則可以指定任何一個列作為分區(qū)列

3. 5.5版本前的RANGE、LIST、HASH分區(qū)要求分區(qū)鍵必須是int;MySQL5.5及以上,支持非整形的RANGE和LIST分區(qū),即:range columns 和 list columns (可以用字符串來進行分區(qū))。

七、分區(qū)命名

1. 分區(qū)的名字基本上遵循其他MySQL 標(biāo)識符應(yīng)當(dāng)遵循的原則,例如用于表和數(shù)據(jù)庫名字的標(biāo)識符。應(yīng)當(dāng)注意的是, 分區(qū)的名字是不區(qū)分大小寫的 。

2. 無論使用何種類型的分區(qū),分區(qū)總是在創(chuàng)建時就自動的順序編號,且從0開始記錄。

八、 創(chuàng)建分區(qū)

1. RANGE分區(qū):

CREATE TABLE `test01` (

`dayid` int(11) DEFAULT NULL,

`mac` varchar(32) NOT NULL DEFAULT '',

`dtype` varchar(50) NOT NULL DEFAULT ''

) ENGINE=InnoDB DEFAULT CHARSET=utf8

/*!50100 PARTITION BY LIST (dayid)

(PARTITION p20171205 VALUES IN (20171205) ENGINE = InnoDB,

PARTITION p20171204 VALUES IN (20171204) ENGINE = InnoDB,

PARTITION p20171206 VALUES IN (20171206) ENGINE = InnoDB,

PARTITION p20171207 VALUES IN (20171207) ENGINE = InnoDB) */

解讀:以上為 uuid小于5時放到p0分區(qū)下,uuid大于5且小于10放到p1分區(qū)下,uuid大于10且小于15放到p2分區(qū)下,uuid大于15 一直到最大值的存在p3分區(qū)下

2. LIST分區(qū):

CREATE TABLE tbl_test (

uuid INT NOT NULL,

title VARCHAR(20)

)

)

PARTITION BY List (uuid) (

PARTITION p0 VALUES in (1,2,3,5),

PARTITION p1 VALUES in (7,9,10),

PARTITION p2 VALUES in (11,15)

)

);

解讀:以上為uuid 等于1/2/3/5時放到p0分區(qū),7/9/10放到p1分區(qū),11/15放到p2分區(qū)。當(dāng)時用insert into時 如果uuid的值不存在p0/p1/p2分區(qū)時,則會插入失敗而報錯。

3. HASH分區(qū):

HASH分區(qū)主要用來確保數(shù)據(jù)在預(yù)先確定數(shù)目的分區(qū)中平均分布。在RANGE分區(qū)和LIST分區(qū)中必須明確指定一個指定的列值或列值集合以指定應(yīng)該保存在哪個分區(qū)中。而在HASH分區(qū)中,MySQL會自動完成這些工作,要做的只是基于將要被哈希的列值指定一個表達式,以及指定被分區(qū)的表將要被分割成的分區(qū)數(shù)量,如:

CREATE TABLE tbl_test (

uuid INT NOT NULL,

title VARCHAR(20)

))

PARTITION BY HASH (uuid) (

PARTITIONS 3

));

解讀:MySQL自動創(chuàng)建3個分區(qū),在執(zhí)行insert into時,根據(jù)插入的uuid通過算法來自動分配區(qū)間。

注意:

(1) 由于每次插入、更新、刪除一行,這個表達式都要計算一次,這意味著非常復(fù)雜的表達式可能會引起性能問題,尤其是在執(zhí)行同時影響大量行的運算(例如批量插入)的時候。

(2) 最有效率的哈希函數(shù)是只對單個表列進行計算,并且它的值隨列值進行一致的增大或減小,因為這考慮了在分區(qū)范圍上的“修剪”。也就是說,表達式值和它所基于的列的值變化越接近,就越能有效地使用該表達式來進行HASH分區(qū)。

3.1:線性HASH分區(qū)

線性HASH分區(qū)在“PARTITION BY”子句中添加“LINEAR”關(guān)鍵字。

線性HASH分區(qū)的有點在于增加、刪除、合并和拆分分區(qū)將變得更加快捷,有利于處理含有及其大量數(shù)據(jù)的表。它的缺點在于各個分區(qū)間數(shù)據(jù)的分布不大可能均衡。

4. KEY分區(qū)

類似于HASH分區(qū),HASH分區(qū)允許用戶自定義的表達式,而KEY分區(qū)則不允許使用用戶自定義的表達式;HASH分區(qū)只支持整數(shù)分區(qū),KEY分區(qū)支持除了blob和text類型之外的其他數(shù)據(jù)類型分區(qū)。

與HASH分區(qū)不同,創(chuàng)建KEY分區(qū)表的時候,可以不指定分區(qū)鍵,默認會選擇使用主鍵或唯一鍵作為分區(qū)鍵,沒有主鍵或唯一鍵,就必須指定分區(qū)鍵。

CREATE TABLE tbl_test (

uuid INT NOT NULL,

title VARCHAR(20)

))

PARTITION BY LINEAR Key (uuid)

PARTITIONS 3;

解讀:根據(jù)分區(qū)鍵來進行分區(qū)

5. 子分區(qū)

子分區(qū)是分區(qū)表中,每個分區(qū)的再次分割,適合保存非常大量的數(shù)據(jù)。

CREATE TABLE tbl_test (

registerTime Date

))

PARTITION BY GANGE(YEAR(registerTime))

SUBPARTITION BY HASH (TO_DAYS(registerTime))

SUBPARTITIONS 2

(

PARTITION p0 VALUES LESS THAN (2017),

PARTITION p1 VALUES LESS THAN (2020),

PARTITION p2 VALUES LESS THAN MAXVALUE

);

解讀:主分區(qū)使用RANGE按照年來進行分區(qū),有3個RANGE分區(qū)。這3個分區(qū)中又被進一步分成了2個子分區(qū),實際上,整個表被分成了3 * 2 = 6個分區(qū)。每個子分區(qū)按照天進行HASH分區(qū)。小于2017的放在一起,2017-2020的放在一起,大于2020的放在一起。

注意:

(1) 在MySQL5.1中,對于已經(jīng)通過RANGE或LIST分區(qū)了的表在進行子分區(qū)是可能的。子分區(qū)既可以使用HASH分區(qū),也可以使用KEY分區(qū)。這也被稱為復(fù)合分區(qū)。

(2) 每個分區(qū)必須有相同數(shù)量的子分區(qū)。

(3) 如果在一個分區(qū)表上的任何分區(qū)上使用SUBPARTITION來明確定義任何子分區(qū),那么就必須定義所有的子分區(qū)。

(4) 每個SUBPARTITION子句必須包含(至少)子分區(qū)的一個名字。

(5) 在每個子分區(qū)內(nèi),子分區(qū)的名字必須是惟一的,目前在整個表中,也要保持唯一。例如:

PARTITION BY RANGE(YEAR(registerTime))

SUBPARTITION BY HASH(TO_DAYS(registerTime))

(

PARTITION p0 VALUES LESS THAN (2017) (

SUBPARTITION s0,

SUBPARTITION s1

),

PARTITION p1 VALUES LESS THAN (2020) (

SUBPARTITION s2,

SUBPARTITION s3

),

PARTITION p2 VALUES LESS THAN MAXVALUE (

SUBPARTITION s4,

SUBPARTITION s5

)

)

子分區(qū)可以用于特別大的表,可以在多個磁盤間分配數(shù)據(jù)和索引。例如:

SUBPARTITION s0

DATA DIRECTORY = '/disk0/data'

INDEX DIRECTORY = '/disk0/idx'

,

,

SUBPARTITION s1

DATA DIRECTORY = '/disk1/data'

INDEX DIRECTORY = '/disk1/idx'

九、MySQL分區(qū)處理NULL值的方式

MySQL中的分區(qū)禁止空值NULL上沒有進行處理,無論它是一個列值還是一個用戶定義表達式的值,一般而言,在這種情況下MySQL把NULL視為0。如果你希望回避這種做法,你應(yīng)該在設(shè)計表時聲明列“NOT NULL”。

十、分區(qū)管理概述

可以對分區(qū)進行添加、刪除、重新定義、合并或拆分等管理操作。

① RANGE和LIST分區(qū)的管理

1. 刪除分區(qū)語句如:alter table tbl_test drop partition p0;

注意:

(1) 當(dāng)刪除了一個分區(qū),也同時刪除了該分區(qū)中所有的數(shù)據(jù)。

(2) 可以通過show create table tbl_test;來查看新的創(chuàng)建表的語句。

(3) 如果是LIST分區(qū)的話,刪除的數(shù)據(jù)不能新增進來,因為這些行的列值包含在已經(jīng)刪除了的分區(qū)的值列表中。

2. 添加分區(qū)語句如:alter table tbl_test add partition(partition p3 values less than(50));

注意:

(1) 對于RANGE分區(qū)的表,只可以添加新的分區(qū)到分區(qū)列表的最高端。

(2) 對于LIST分區(qū)的表,不能添加已經(jīng)包含在現(xiàn)有分區(qū)值列表中的任意值。

3. 如果希望能不丟失數(shù)據(jù)的條件下重新定義分區(qū),可以使用如下語句:

ALTER TABLE tbl_name REORGANIZE PARTITION partition_list INTO(partition_definitions)

(1) 拆分分區(qū)如:

ALTER TABLE tbl_name REORGANIZE PARTITION partition_list INTO(partition s0 values less than(5),partition s1 values less than(10));

或者如:

ALTER TABLE tbl_name REORGANIZE PARTITION p0 INTO(partition s0 values in(1,2,3), partition s1 values in(4,5));

(2) 合并分區(qū)如:ALTER TABLE tbl_name REORGANIZE PARTITION s0,s1 INTO(partition p0 values in(1,2,3,4,5));

4. 刪除所有分區(qū),但保留數(shù)據(jù),形式:ALTER TABLE tbl_name remove partitioning;

② HASH和KEY分區(qū)的管理

1. 減少分區(qū)數(shù)量語句如:ALTER TABLE tbl_name COALESCE PARTITION 2;

2. 添加分區(qū)數(shù)量語句如:ALTER TABLE tbl_name add PARTITION partitions 2;

③ 其他分區(qū)管理語句

1. 重建分區(qū) :類似于先刪除保存在分區(qū)中的所有記錄,然后重新插入它們,可用于整理分區(qū)碎片。如:ALTER table tbl_name REBUILD PARTITION p2,p3;

2. 優(yōu)化分區(qū) :如果從分區(qū)中刪除了大量的行,或者對一個帶有可變長度的行(也就是說,有VARCHAR,BLOB或TEXT類型的列)做了許多修改,可以使用 ALTER TABLE tbl_name OPTIMIZE PARTITION來收回沒有使用的空間,并整理分區(qū)數(shù)據(jù)文件的碎片。如:ALTER TABLE tbl_name OPTIMIZE PARTITION p2,p3;

3. 分析分區(qū) :讀取并保存分區(qū)的鍵分布,如:ALTER TABLE tbl_name ANALYZE PARTITION p2,p3;

4. 檢查分區(qū) :檢查分區(qū)中的數(shù)據(jù)或索引是否已經(jīng)被破壞,如:ALTER TABLE tbl_name CHECK PARTITION p2,p3;

5. 修補分區(qū) :修補被破壞的分區(qū),如:ALTER TABLE tbl_name REPAIR PARTITION p2,p3;

十、查看分區(qū)信息

1. 查看分區(qū)信息:select * from information_schema.partitions where table_schema='arch1' and table_name = 'tbl_test' G;

2. 查看分區(qū)上的數(shù)據(jù):select * from tbl_test partition(p0);

3. 查看MySQL會操作的分區(qū):explain partitions select * from tbl_test where uuid = 2;

十一、 局限性

1. 最大分區(qū)數(shù)目不能超過1024,一般建議對單表的分區(qū)數(shù)不要超過50個。

2. 如果含有唯一索引或者主鍵,則分區(qū)列必須包含在所有的唯一索引或者主鍵在內(nèi)。

3. 不支持外鍵。

4. 不支持全文索引,對分區(qū)表的分區(qū)鍵創(chuàng)建索引,那么這個索引也將被分區(qū)。

5. 按日期進行分區(qū)很合適,因為很多日期函數(shù)可以用。但是對字符串來說合適的分區(qū)函數(shù)不太多。

6. 只有RANGE和LIST分區(qū)能進行子分區(qū),HASH和KEY分區(qū)不能進行子分區(qū)。

7. 臨時表不能被分區(qū)。

8. 分區(qū)表對于單條記錄的查詢沒有優(yōu)勢。

9. 要注意選擇分區(qū)的成本,沒插入一行數(shù)據(jù)都需要按照表達式篩選插入的分區(qū)。

10. 分區(qū)字段盡量不要可以為null

MySQL按月自動創(chuàng)建分區(qū)表(千萬級大表優(yōu)化)

對用戶來說,分區(qū)表是一個獨立的邏輯表,但是底層由多個物理子表組成,實現(xiàn)分區(qū)的代碼實際上是通過對一組底層表的對象封裝,但對SQL層來說是一個完全封裝底層的黑盒子。

MySQL實現(xiàn)分區(qū)的方式也意味著索引也是按照分區(qū)的子表定義, 沒有全局索引 。

分區(qū)的意思是指將同一表中不同行的記錄分配到不同的物理文件中 ,幾個分區(qū)就有幾個.idb文件。MySQL數(shù)據(jù)庫的分區(qū)是局部分區(qū)索引,一個分區(qū)中既存了數(shù)據(jù),又放了索引。也就是說,每個區(qū)的聚集索引和非聚集索引都放在各自區(qū)的(不同的物理文件)。

1、可以讓單表 存儲更多的數(shù)據(jù) 。

2、 分區(qū)表的數(shù)據(jù)更容易維護 ,可以通過刪除與那些數(shù)據(jù)有關(guān)的分區(qū),更容易刪除數(shù)據(jù),也可以增加新的分區(qū)來支持新插入的數(shù)據(jù)。另外,還可以對一個獨立分區(qū)進行優(yōu)化、檢查、修復(fù)等操作。

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

4、通過跨多個磁盤來分散數(shù)據(jù)查詢,來 獲得更大的查詢吞吐量 。

要使定時事件起作用,MySQL的常量GLOBAL event_scheduler必須為on或者是1。

1、查看scheduler的當(dāng)前狀態(tài):

2、修改scheduler狀態(tài)為打開(0:off , 1:on):

3、臨時打開定時器(四種方法):

4、永久生效的方法,修改配置文件my點吸煙 f

5、臨時開啟某個事件

6、臨時關(guān)閉某個事件

MySQL數(shù)據(jù)庫性能優(yōu)化之分區(qū)分表分庫

分表是分散數(shù)據(jù)庫壓力的好方法。

分表,最直白的意思,就是將一個表結(jié)構(gòu)分為多個表,然后,可以再同一個庫里,也可以放到不同的庫。

當(dāng)然,首先要知道什么情況下,才需要分表。個人覺得單表記錄條數(shù)達到百萬到千萬級別時就要使用分表了。

分表的分類

**1、縱向分表**

將本來可以在同一個表的內(nèi)容,人為劃分為多個表。(所謂的本來,是指按照關(guān)系型數(shù)據(jù)庫的第三范式要求,是應(yīng)該在同一個表的。)

分表理由:根據(jù)數(shù)據(jù)的活躍度進行分離,(因為不同活躍的數(shù)據(jù),處理方式是不同的)

案例:

對于一個博客系統(tǒng),文章標(biāo)題,作者,分類,創(chuàng)建時間等,是變化頻率慢,查詢次數(shù)多,而且最好有很好的實時性的數(shù)據(jù),我們把它叫做冷數(shù)據(jù)。而博客的瀏覽量,回復(fù)數(shù)等,類似的統(tǒng)計信息,或者別的變化頻率比較高的數(shù)據(jù),我們把它叫做活躍數(shù)據(jù)。所以,在進行數(shù)據(jù)庫結(jié)構(gòu)設(shè)計的時候,就應(yīng)該考慮分表,首先是縱向分表的處理。

這樣縱向分表后:

首先存儲引擎的使用不同,冷數(shù)據(jù)使用MyIsam 可以有更好的查詢數(shù)據(jù)?;钴S數(shù)據(jù),可以使用Innodb ,可以有更好的更新速度。

其次,對冷數(shù)據(jù)進行更多的從庫配置,因為更多的操作時查詢,這樣來加快查詢速度。對熱數(shù)據(jù),可以相對有更多的主庫的橫向分表處理。

其實,對于一些特殊的活躍數(shù)據(jù),也可以考慮使用memcache ,redis之類的緩存,等累計到一定量再去更新數(shù)據(jù)庫?;蛘適ongodb 一類的nosql 數(shù)據(jù)庫,這里只是舉例,就先不說這個。

**2、橫向分表**

字面意思,就可以看出來,是把大的表結(jié)構(gòu),橫向切割為同樣結(jié)構(gòu)的不同表,如,用戶信息表,user_1,user_2等。表結(jié)構(gòu)是完全一樣,但是,根據(jù)某些特定的規(guī)則來劃分的表,如根據(jù)用戶ID來取模劃分。

分表理由:根據(jù)數(shù)據(jù)量的規(guī)模來劃分,保證單表的容量不會太大,從而來保證單表的查詢等處理能力。

案例:同上面的例子,博客系統(tǒng)。當(dāng)博客的量達到很大時候,就應(yīng)該采取橫向分割來降低每個單表的壓力,來提升性能。例如博客的冷數(shù)據(jù)表,假如分為100個表,當(dāng)同時有100萬個用戶在瀏覽時,如果是單表的話,會進行100萬次請求,而現(xiàn)在分表后,就可能是每個表進行1萬個數(shù)據(jù)的請求(因為,不可能絕對的平均,只是假設(shè)),這樣壓力就降低了很多很多。

延伸:為什么要分表和分區(qū)?

日常開發(fā)中我們經(jīng)常會遇到大表的情況,所謂的大表是指存儲了百萬級乃至千萬級條記錄的表。這樣的表過于龐大,導(dǎo)致數(shù)據(jù)庫在查詢和插入的時候耗時太長,性能低下,如果涉及聯(lián)合查詢的情況,性能會更加糟糕。分表和表分區(qū)的目的就是減少數(shù)據(jù)庫的負擔(dān),提高數(shù)據(jù)庫的效率,通常點來講就是提高表的增刪改查效率。

什么是分表?

分表是將一個大表按照一定的規(guī)則分解成多張具有獨立存儲空間的實體表,我們可以稱為子表,每個表都對應(yīng)三個文件,MYD數(shù)據(jù)文件,.MYI索引文件,.frm表結(jié)構(gòu)文件。這些子表可以分布在同一塊磁盤上,也可以在不同的機器上。app讀寫的時候根據(jù)事先定義好的規(guī)則得到對應(yīng)的子表名,然后去操作它。

什么是分區(qū)?

分區(qū)和分表相似,都是按照規(guī)則分解表。不同在于分表將大表分解為若干個獨立的實體表,而分區(qū)是將數(shù)據(jù)分段劃分在多個位置存放,可以是同一塊磁盤也可以在不同的機器。分區(qū)后,表面上還是一張表,但數(shù)據(jù)散列到多個位置了。app讀寫的時候操作的還是大表名字,db自動去組織分區(qū)的數(shù)據(jù)。

**MySQL分表和分區(qū)有什么聯(lián)系呢?**

1、都能提高mysql的性高,在高并發(fā)狀態(tài)下都有一個良好的表現(xiàn)。

2、分表和分區(qū)不矛盾,可以相互配合的,對于那些大訪問量,并且表數(shù)據(jù)比較多的表,我們可以采取分表和分區(qū)結(jié)合的方式(如果merge這種分表方式,不能和分區(qū)配合的話,可以用其他的分表試),訪問量不大,但是表數(shù)據(jù)很多的表,我們可以采取分區(qū)的方式等。

3、分表技術(shù)是比較麻煩的,需要手動去創(chuàng)建子表,app服務(wù)端讀寫時候需要計算子表名。采用merge好一些,但也要創(chuàng)建子表和配置子表間的union關(guān)系。

4、表分區(qū)相對于分表,操作方便,不需要創(chuàng)建子表。

我們知道對于大型的互聯(lián)網(wǎng)應(yīng)用,數(shù)據(jù)庫單表的數(shù)據(jù)量可能達到千萬甚至上億級別,同時面臨這高并發(fā)的壓力。Master-Slave結(jié)構(gòu)只能對數(shù)據(jù)庫的讀能力進行擴展,寫操作還是集中在Master中,Master并不能無限制的掛接Slave庫,如果需要對數(shù)據(jù)庫的吞吐能力進行進一步的擴展,可以考慮采用分庫分表的策略。

**1、分表**

在分表之前,首先要選中合適的分表策略(以哪個字典為分表字段,需要將數(shù)據(jù)分為多少張表),使數(shù)據(jù)能夠均衡的分布在多張表中,并且不影響正常的查詢。在企業(yè)級應(yīng)用中,往往使用org_id(組織主鍵)做為分表字段,在互聯(lián)網(wǎng)應(yīng)用中往往是userid。在確定分表策略后,當(dāng)數(shù)據(jù)進行存儲及查詢時,需要確定到哪張表里去查找數(shù)據(jù),

數(shù)據(jù)存放的數(shù)據(jù)表 = 分表字段的內(nèi)容 % 分表數(shù)量

**2、分庫**

分表能夠解決單表數(shù)據(jù)量過大帶來的查詢效率下降的問題,但是不能給數(shù)據(jù)庫的并發(fā)訪問帶來質(zhì)的提升,面對高并發(fā)的寫訪問,當(dāng)Master無法承擔(dān)高并發(fā)的寫入請求時,不管如何擴展Slave服務(wù)器,都沒有意義了。我們通過對數(shù)據(jù)庫進行拆分,來提高數(shù)據(jù)庫的寫入能力,即所謂的分庫。分庫采用對關(guān)鍵字取模的方式,對數(shù)據(jù)庫進行路由。

數(shù)據(jù)存放的數(shù)據(jù)庫=分庫字段的內(nèi)容%數(shù)據(jù)庫的數(shù)量

**3、即分表又分庫**

數(shù)據(jù)庫分表可以解決單表海量數(shù)據(jù)的查詢性能問題,分庫可以解決單臺數(shù)據(jù)庫的并發(fā)訪問壓力問題。

當(dāng)數(shù)據(jù)庫同時面臨海量數(shù)據(jù)存儲和高并發(fā)訪問的時候,需要同時采取分表和分庫策略。一般分表分庫策略如下:

中間變量 = 關(guān)鍵字%(數(shù)據(jù)庫數(shù)量*單庫數(shù)據(jù)表數(shù)量)

庫 = 取整(中間變量/單庫數(shù)據(jù)表數(shù)量)

表 = (中間變量%單庫數(shù)據(jù)表數(shù)量)

實例:

1、分庫分表

很明顯,一個主表(也就是很重要的表,例如用戶表)無限制的增長勢必嚴重影響性能,分庫與分表是一個很不錯的解決途徑,也就是性能優(yōu)化途徑,現(xiàn)在的案例是我們有一個1000多萬條記錄的用戶表members,查詢起來非常之慢,同事的做法是將其散列到100個表中,分別從members0到members99,然后根據(jù)mid分發(fā)記錄到這些表中,牛逼的代碼大概是這樣子:

復(fù)制代碼 代碼如下:

?php

for($i=0;$i 100; $i++ ){

//echo "CREATE TABLE db2.members{$i} LIKE db1.members

";

echo "INSERT INTO members{$i} SELECT * FROM members WHERE mid%100={$i}

";

}

?

2、不停機修改mysql表結(jié)構(gòu)

同樣還是members表,前期設(shè)計的表結(jié)構(gòu)不盡合理,隨著數(shù)據(jù)庫不斷運行,其冗余數(shù)據(jù)也是增長巨大,同事使用了下面的方法來處理:

先創(chuàng)建一個臨時表:

/*創(chuàng)建臨時表*/

CREATE TABLE members_tmp LIKE members

然后修改members_tmp的表結(jié)構(gòu)為新結(jié)構(gòu),接著使用上面那個for循環(huán)來導(dǎo)出數(shù)據(jù),因為1000萬的數(shù)據(jù)一次性導(dǎo)出是不對的,mid是主鍵,一個區(qū)間一個區(qū)間的導(dǎo),基本是一次導(dǎo)出5萬條吧,這里略去了

接著重命名將新表替換上去:

/*這是個頗為經(jīng)典的語句哈*/

RENAME TABLE members TO members_bak,members_tmp TO members;

就是這樣,基本可以做到無損失,無需停機更新表結(jié)構(gòu),但實際上RENAME期間表是被鎖死的,所以選擇在線少的時候操作是一個技巧。經(jīng)過這個操作,使得原先8G多的表,一下子變成了2G多。


名稱欄目:mysql表分區(qū)怎么優(yōu)化 mysql 表分區(qū)性能提升不大
當(dāng)前鏈接:http://weahome.cn/article/ddedhdo.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部