Composite(復合模式) - 很神秘吧,哈哈,其實是以上模式的組合使用而已,就不解釋了。舉例:在初始化已經進行了Range范圍分區的表上,我們可以對其中一個分區再進行hash哈希分區。
分區帶來的好處太多太多了,有多少?俺也不知道,自己猜去吧,要是覺得沒有多少就別用,反正俺也不求你用。不過在這裡俺強調兩點好處:
性能的提升(Increased performance) - 在掃描操作中,如果MySQL的優化器知道哪個分區中才包含特定查詢中需要的數據,它就能直接去掃描那些分區的數據,而不用浪費很多時間掃描不需要的地方了。需要舉個例子?好啊,百萬行的表劃分為10個分區,每個分區就包含十萬行數據,那麼查詢分區需要的時間僅僅是全表掃描的十分之一了,很明顯的對比。同時對十萬行的表建立索引的速度也會比百萬行的快得多得多。如果你能把這些分區建立在不同的磁盤上,這時候的I/O讀寫速度就“不堪設想”(沒用錯詞,真的太快了,理論上100倍的速度提升啊,這是多麼快的響應速度啊,所以有點不堪設想了)了。 對數據管理的簡化(SimplifIEd data management) - 分區技術可以讓DBA對數據的管理能力提升。通過優良的分區,DBA可以簡化特定數據操作的執行方式。例如:DBA在對某些分區的內容進行刪除的同時能保證余下的分區的數據完整性(這是跟對表的數據刪除這種大動作做比較的)。 此外分區是由MySQL系統直接管理的,DBA不需要手工的去劃分和維護。例如:這個例如沒意思,不講了,如果你是DBA,只要你劃分了分區,以後你就不用管了就是了。
站在性能設計的觀點上,俺們對以上的內容也是相當感興趣滴。通過使用分區和對不同的SQL操作的匹配設計,數據庫的性能一定能獲得巨大提升。下面咱們一起用用這個MySQL 5.1的新功能看看。
下面所有的測試都在Dell Optiplex box with a Pentium 4 3.00GHz processor, 1GB of RAM機器上(炫耀啊……),Fedora Core 4和MySQL 5.1.6 alpha上運行通過。
如何進行實際分區 看看分區的實際效果吧。我們建立幾個同樣的MyISAM引擎的表,包含日期敏感的數據,但只對其中一個分區。分區的表(表名為part_tab)我們采用Range范圍分區模式,通過年份進行分區: MySQL> CREATE TABLE part_tab -> ( c1 int default NULL, -> c2 varchar(30) default NULL, -> c3 date default NULL -> -&g
-> c3 date default NULL) engine=myisam; Query OK, 0 rows affected (0.02 sec) 下面咱寫一個存儲過程(感謝Peter Gulutzan給的代碼,如果大家需要Peter Gulutzan的存儲過程教程的中文翻譯也可以跟我要,chenpengyi◎gmail.com),它能向咱剛才建立的已分區的表中平均的向每個分區插入共8百萬條不同的數據。填滿後,咱就給沒分區的克隆表中插入相同的數據: mysql> delimiter // mysql> CREATE PROCEDURE load_part_tab() -> begin -> declare v int default 0; -> while v < 8000000 -> do -> insert into part_tab -> values (v,'testing partitions',adddate('1995-01-01',(rand(v)*36520) mod 3652)); -> set v = v + 1; -> end while; -> end -> // Query OK, 0 rows affected (0.00 sec) mysql> delimiter ; mysql> call load_part_tab(); Query OK, 1 row affected (8 min 17.75 sec) MySQL> insert into no_part_tab select * from part_tab; Query OK, 8000000 rows affected (51.59 sec) Records: 8000000 Duplicates: 0 Warnings: 0
表都准備好了。咱開始對這兩表中的數據進行簡單的范圍查詢吧。先分區了的,後沒分區的,跟著有執行過程解析(MySQL Explain命令解析器),可以看到MySQL做了什麼: MySQL> select count(*) from no_part_tab where -> c3 >
******** id: 1 select_type: SIMPLE table: part_tab partitions: p1 type: ALL possible_keys: NULL key: NULL key_len: NULL ref: NULL rows: 798458 Extra: Using where 1 row in set (0.00 sec) 從上面結果可以容易看出,設計恰當表分區能比非分區的減少90%的響應時間。而命令解析Explain程序也告訴我們在對已分區的表的查詢過程中僅對第一個分區進行了掃描,其他都跳過了。 哔厲吧拉,說阿說……反正就是這個分區功能對DBA很有用拉,特別對VLDB和需要快速反應的系統。
對Vertical Partitioning的一些看法 雖然MySQL 5.1自動實現了水平分區,但在設計數據庫的時候不要輕視垂直分區。雖然要手工去實現垂直分區,但在特定場合下你會收益不少的。例如在前面建立的表中,VARCHAR字段是你平常很少引用的,那麼對它進行垂直分區會不會提升速度呢?咱們看看測試結果: mysql> desc part_tab; +-------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+-------+ | c1 | int(11) | YES | | NULL | | | c2 | varchar(30) | YES | | NULL | | | c3 | date | YES | | NULL | | +-------+-------------+------+-----+---------+-------+ 3 rows in set (0.03 sec) mysql> alter table part_tab drop column c2; Query OK, 8000000 rows affected (42.20 sec) Records: 8000000 Duplicates: 0 Warnings: 0 mysql> desc part_tab; +-------+---------+------+-----+---------+-------+ | FIEld | Type | Null | Key | Default | Extra | +-------+---------+------+-----+---------+-------+ | c1 | int(11) | YES | | NULL | | | c3 | date | YES | | NULL | | +-------+---------+------+-----+---------+-------+ 2 rows in set (0.00 sec) MySQL> select count(*) from part_tab where -> c3 > date '1995-01-01' and c3 < date '1995-12-31'; +----------+ | count(*) | +----------+ | 795181 | +----------+ 1 row in set (0.34 sec) 在設計上去掉了VARCHAR字段後,不止是你,俺也發現查詢響應速度上獲得了另一個90%的時間節省。所以大家在設計表的時候,一定要考慮,表中的字段是否真正關聯,又是否在你的查詢中有用?
補充說明
這麼簡單的文章肯定不能說全MySQL 5.1 分區機制的所有好處和要點(雖然對自己寫文章水平很有信心),下面就說幾個感興趣的:
包括本地索引local indexes,對其進行的是一對一的視圖鏡像,假設一個表有十個分區,那麼其本地索引也包含十個分區。