一、什么是表分區
通俗地講表分區是將一大表,根據條件分割成若干個小表。mysql5.1開始支持數據表分區了。
如:某用戶表的記錄超過了1000萬條,那么就可以根據入庫日期將表分區,也可以根據所在地將表分區。當然也可根據其他的條件分區。
二、為什么要對表進行分區
為了改善大型表以及具有各種訪問模式的表的可伸縮性,可管理性和提高數據庫效率。
分區的一些優點包括:
1)、與單個磁盤或文件系統分區相比,可以存儲更多的數據。
2)、對於那些已經失去保存意義的數據,通常可以通過刪除與那些數據有關的分區,很容易地刪除那些數據。相反地,在某些情況下,添加新數據的過程又可以通過為那些新數據專門增加一個新的分區,來很方便地實現。通常和分區有關的其他優點包括下面列出的這些。MySQL分區中的這些功能目前還沒有實現,但是在我們的優先級列表中,具有高的優先級;我們希望在5.1的生產版本中,能包括這些功能。
3)、一些查詢可以得到極大的優化,這主要是借助於滿足一個給定WHERE語句的數據可以只保存在一個或多個分區內,這樣在查找時就不用查找其他剩余的分區。因為分區可以在創建了分區表后進行修改,所以在第一次配置分區方案時還不曾這么做時,可以重新組織數據,來提高那些常用查詢的效率。
4)、涉及到例如SUM()和COUNT()這樣聚合函數的查詢,可以很容易地進行並行處理。這種查詢的一個簡單例子如 “SELECT salesperson_id, COUNT (orders) as order_total FROM sales GROUP BY salesperson_id;”。通過“並行”,這意味着該查詢可以在每個分區上同時進行,最終結果只需通過總計所有分區得到的結果。
5)、通過跨多個磁盤來分散數據查詢,來獲得更大的查詢吞吐量。
三、分區類型
· RANGE分區:基於屬於一個給定連續區間的列值,把多行分配給分區。
· LIST分區:類似於按RANGE分區,區別在於LIST分區是基於列值匹配一個離散值集合中的某個值來進行選擇。
· HASH分區:基於用戶定義的表達式的返回值來進行選擇的分區,該表達式使用將要插入到表中的這些行的列值進行計算。這個函數可以包含MySQL 中有效的、產生非負整數值的任何表達式。
· KEY分區:類似於按HASH分區,區別在於KEY分區只支持計算一列或多列,且MySQL 服務器提供其自身的哈希函數。必須有一列或多列包含整數值。
1.RANGE分區
基於屬於一個給定連續區間的列值,把多行分配給分區。這些區間要連續且不能相互重疊,使用VALUES LESS THAN操作符來進行定義。以下是實例。
2.LIST分區
類似於按RANGE分區,區別在於LIST分區是基於列值匹配一個離散值集合中的某個值來進行選擇。
LIST分區通過使用“PARTITION BY LIST(expr)”來實現,其中“expr” 是某列值或一個基於某個列值、並返回一個整數值的表達式,然后通過“VALUES IN (value_list)”的方式來定義每個分區,其中“value_list”是一個通過逗號分隔的整數列表。
3.HASH分區
基於用戶定義的表達式的返回值來進行選擇的分區,該表達式使用將要插入到表中的這些行的列值進行計算。這個函數可以包含MySQL 中有效的、產生非負整數值的任何表達式。
要使用HASH分區來分割一個表,要在CREATE TABLE 語句上添加一個“PARTITION BY HASH (expr)”子句,其中“expr”是一個返回一個整數的表達式。它可以僅僅是字段類型為MySQL 整型的一列的名字。此外,你很可能需要在后面再添加一個“PARTITIONS num”子句,其中num 是一個非負的整數,它表示表將要被分割成分區的數量。
4.KSY分區
類似於按HASH分區,區別在於KEY分區只支持計算一列或多列,且MySQL 服務器提供其自身的哈希函數。必須有一列或多列包含整數值。
不同的表分區對比如下:
下面來操作MySQL表分實例操作主要講解 Range分區技術
注意為了查看方便我這邊對mysql操作都是用客戶端工具Navicat For Mysql 進行連接操作。
1.創建分區表,按日期和年份拆分 使用的是 myisam 引擎
-- 創建表分區,按日期的年份拆分 create table part_tab(c1 int default null,c2 varchar(30) default null,c3 date default null) engine=myisam PARTITION by range(year(c3))( PARTITION p0 values less than(2007), PARTITION p1 values less than(2008), PARTITION p2 values less than(2009), PARTITION p3 values less than(2010), PARTITION p4 values less than(2011), PARTITION p5 values less than(2012), PARTITION p6 values less than(2013), PARTITION p7 values less than(2014), PARTITION p8 values less than(2015), PARTITION p9 values less than(2016), PARTITION p10 values less than MAXVALUE); -- 最后一行 ,考慮可能 最大值 默認分區
2.創建未分區表,主要用於作對比表字段和結構和分區表一模一樣。
create table no_part_tab(c1 int default null,c2 varchar(30) default null,c3 date default null) engine=myisam;
3.創建測試數據這里使用存儲過程快速創建100萬行數據測試數據越多越方便查看,這里只測試100萬行根據個人需求插入,因只是用日期分區,其他列不住細節深究。只關注日期列。
create PROCEDURE load_part_tab() begin declare i int default 0; while i<1000000 do insert into part_tab values(i,'test data part', adddate('2007-01-01',(rand(i)*36520) mod 3652)); set i=i+1; end while; end;
4.執行存儲過程插入數據
call load_part_tab();
5.進入查看我們剛才的分區表,數據庫安裝都是常規的路徑,測試數據名稱為test
[root@localhost /]# cd usr/local/mysql/data/test [root@localhost test]# ls
顯示如上信息說明已經創建完成。
6.復制數據到未分區表no_part_tab
insert into no_part_tab select *from part_tab;
7.測試SQL 的性能分別查詢1年的數據。
7.1)分區表的性能
7.2)未分區表的性能
查詢時間非常明顯的區別,注意數據量越大越明顯。
8.為何會分區會有如此大的區別我們通過查詢計划分析。
8.1)分區的查詢計划影響的行數是:99813
8.2)未分區查詢計划影響的行數是:1000000
很明顯查詢條件的數據是在p1分區 所以查詢的只會查詢這分區,查詢效果就顯而易見。
9.增加未索引字段查詢
select * from part_tab where c3>date'2007-01-01' and c3<date'2017-12-31' and c2='mysql';
查看執行時間2.55s
select * from no_part_tab where c3>date'2007-01-01' and c3<date'2017-12-31' and c2='mysql';
查看執行時間11.16s
對比時間差距還是很大的具體查詢時間根據個人計算機性能已經數據大小進行測試,數據量越大越明顯。
四.innodb表分區
在innodb數據庫引擎中要把分區技術做成功必須設置表為獨立表空間特別注意這點。
1.什么是共享表空間和獨立表空間
貢獻表空間已經獨立表空間都是針對數據的存儲方式而言的。
貢獻表空間:某一個數據庫的所有的表數據,索引文件全部放在一個文件中,默認這個共享表空間的文件路徑在data目錄下。默認的文件名為ibdata1初始大小為10M。
獨占表空間:每個表都將會生成意獨立文件方式來進行存儲,每個表都有一個.frm表描述,還有一個.dbd文件.其中這個文件包括了單獨一個表數據內容以及索引內容,默認情況下它的存儲位置也是在表的位置之中。
2.共享表空間:
優點:
可以放表空間分成多文件存放各個磁盤上(表空間文件大小不受表大小的限制,如一個表可以分布在不同的文件上)。
數據和文件放一起方便管理。
缺點:
所有的數據和索引存放到一個文件中講有一個很大的文件,雖然可以把一個大文件分成多個小文件,但是多個表及索引在表空間中混合存儲,這樣對於一個表做了大量刪除操作后表空間中將會有大量的空隙,特別是對於統計分析,日志系統這類應用最不合適用共享表空間。
3.實際操作
開啟innodb數據庫引擎獨立表空間。
編輯my.cnf 增加innodb_file_per_table=1
[root@localhost test]# vi /etc/my.cnf
只有設置了innodb 引擎的獨立表空間才能做成功表分區,特別注意。