<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    朋的博客

    MySQL資料,Java技術(shù),管理思想,博弈論,Ajax,XP極限編程,H.264,HEVC,HDR
    隨筆 - 86, 文章 - 59, 評論 - 1069, 引用 - 0
    數(shù)據(jù)加載中……

    通過分區(qū)(Partition)提升MySQL性能[原創(chuàng)翻譯]

    通過分區(qū)(Partition)提升MySQL性能

    ?????????????? ——MySQL5.1新特性翻譯系列

    幾年前,俺寫過一篇題為“The Foundation of Excellent Performance”的文章(現(xiàn)在仍然可以在http://www.tdan.com/i016fe03.htm看到),俺對SQL語句是影響數(shù)據(jù)庫驅(qū)動系統(tǒng)性能的第一要素的觀點有點質(zhì)疑。其實在那時我在文章中就堅信數(shù)據(jù)庫的物理設(shè)計在對高級數(shù)據(jù)庫的性能影響上遠比其他因素重要。同時俺還給大家看了Oracle的研究,他們解釋了為什么拙劣的物理設(shè)計是數(shù)據(jù)庫停機(無論是有計劃的還是沒計劃的)背后的主要原因。這么多年都過來啦(幸好沒多少人朝俺扔磚頭),俺的觀點是改變了一些,但在這點上俺還是堅持DBA如果想要高性能的數(shù)據(jù)庫就必須在數(shù)據(jù)庫的物理設(shè)計上多思考的觀點,這樣才能減少響應(yīng)時間使終端用戶滿意而不是引來罵聲一片。(陳朋奕語:不要那么嚴(yán)肅,嘿嘿)

    俺今天這么激動又想寫文章的原因是MySQL5.1的發(fā)布帶來了設(shè)計超強動力數(shù)據(jù)庫的強有力的武器,任何MySQLDBA都應(yīng)該盡快學(xué)習(xí)并使用它。俺覺得如果能很好滴使用這個5.1版帶來的新特性,DBA可以使自己管理的VLDB(不知道什么是VLDB?告訴你,是好大好大的數(shù)據(jù)庫的意思,Very Large DB)或數(shù)據(jù)倉庫奇跡般的獲得巨大的性能提升。


    什么是數(shù)據(jù)庫分區(qū)?

    數(shù)據(jù)庫分區(qū)是一種物理數(shù)據(jù)庫設(shè)計技術(shù),DBA和數(shù)據(jù)庫建模人員對其相當(dāng)熟悉。雖然分區(qū)技術(shù)可以實現(xiàn)很多效果,但其主要目的是為了在特定的SQL操作中減少數(shù)據(jù)讀寫的總量以縮減響應(yīng)時間。

    分區(qū)主要有兩種形式://這里一定要注意行和列的概念(row是行,column是列)

    1. 水平分區(qū)(Horizontal Partitioning 這種形式分區(qū)是對表的行進行分區(qū),通過這樣的方式不同分組里面的物理列分割的數(shù)據(jù)集得以組合,從而進行個體分割(單分區(qū))或集體分割(1個或多個分區(qū))。所有在表中定義的列在每個數(shù)據(jù)集中都能找到,所以表的特性依然得以保持。
      舉個簡單例子:一個包含十年發(fā)票記錄的表可以被分區(qū)為十個不同的分區(qū),每個分區(qū)包含的是其中一年的記錄。(朋奕注:這里具體使用的分區(qū)方式我們后面再說,可以先說一點,一定要通過某個屬性列來分割,譬如這里使用的列就是年份)
    2. 垂直分區(qū)(Vertical Partitioning 這種分區(qū)方式一般來說是通過對表的垂直劃分來減少目標(biāo)表的寬度,使某些特定的列被劃分到特定的分區(qū),每個分區(qū)都包含了其中的列所對應(yīng)的行。
      舉個簡單例子:一個包含了大textBLOB列的表,這些textBLOB列又不經(jīng)常被訪問,這時候就要把這些不經(jīng)常使用的textBLOB了劃分到另一個分區(qū),在保證它們數(shù)據(jù)相關(guān)性的同時還能提高訪問速度。

    在數(shù)據(jù)庫供應(yīng)商開始在他們的數(shù)據(jù)庫引擎中建立分區(qū)(主要是水平分區(qū))時,DBA和建模者必須設(shè)計好表的物理分區(qū)結(jié)構(gòu),不要保存冗余的數(shù)據(jù)(不同表中同時都包含父表中的數(shù)據(jù))或相互聯(lián)結(jié)成一個邏輯父對象(通常是視圖)。這種做法會使水平分區(qū)的大部分功能失效,有時候也會對垂直分區(qū)產(chǎn)生影響。



    在MySQL 5.1中進行分區(qū)

    ?????MySQL5.1中最激動人心的新特性應(yīng)該就是對水平分區(qū)的支持了。這對MySQL的使用者來說確實是個好消息,而且她已經(jīng)支持分區(qū)大部分模式:

    ?????????Range(范圍) – 這種模式允許DBA將數(shù)據(jù)劃分不同范圍。例如DBA可以將一個表通過年份劃分成三個分區(qū),80年代(1980's)的數(shù)據(jù),90年代(1990's)的數(shù)據(jù)以及任何在2000年(包括2000年)后的數(shù)據(jù)。?
    ?????????Hash(哈希) – 這中模式允許DBA通過對表的一個或多個列的Hash Key進行計算,最后通過這個Hash碼不同數(shù)值對應(yīng)的數(shù)據(jù)區(qū)域進行分區(qū),。例如DBA可以建立一個對表主鍵進行分區(qū)的表。?
    ?????????Key(鍵值) – 上面Hash模式的一種延伸,這里的Hash Key是MySQL系統(tǒng)產(chǎn)生的。?
    ?????????List(預(yù)定義列表) – 這種模式允許系統(tǒng)通過DBA定義的列表的值所對應(yīng)的行數(shù)據(jù)進行分割。例如:DBA建立了一個橫跨三個分區(qū)的表,分別根據(jù)2004年2005年和2006年值所對應(yīng)的數(shù)據(jù)。?
    ?????????Composite(復(fù)合模式) - 很神秘吧,哈哈,其實是以上模式的組合使用而已,就不解釋了。舉例:在初始化已經(jīng)進行了Range范圍分區(qū)的表上,我們可以對其中一個分區(qū)再進行hash哈希分區(qū)。

    ????分區(qū)帶來的好處太多太多了,有多少?俺也不知道,自己猜去吧,要是覺得沒有多少就別用,反正俺也不求你用。不過在這里俺強調(diào)兩點好處:

    性能的提升(Increased performance) - 在掃描操作中,如果MySQL的優(yōu)化器知道哪個分區(qū)中才包含特定查詢中需要的數(shù)據(jù),它就能直接去掃描那些分區(qū)的數(shù)據(jù),而不用浪費很多時間掃描不需要的地方了。需要舉個例子?好啊,百萬行的表劃分為10個分區(qū),每個分區(qū)就包含十萬行數(shù)據(jù),那么查詢分區(qū)需要的時間僅僅是全表掃描的十分之一了,很明顯的對比。同時對十萬行的表建立索引的速度也會比百萬行的快得多得多。如果你能把這些分區(qū)建立在不同的磁盤上,這時候的I/O讀寫速度就“不堪設(shè)想”(沒用錯詞,真的太快了,理論上100倍的速度提升啊,這是多么快的響應(yīng)速度啊,所以有點不堪設(shè)想了)了。

    對數(shù)據(jù)管理的簡化(Simplified data management) - 分區(qū)技術(shù)可以讓DBA對數(shù)據(jù)的管理能力提升。通過優(yōu)良的分區(qū),DBA可以簡化特定數(shù)據(jù)操作的執(zhí)行方式。例如:DBA在對某些分區(qū)的內(nèi)容進行刪除的同時能保證余下的分區(qū)的數(shù)據(jù)完整性(這是跟對表的數(shù)據(jù)刪除這種大動作做比較的)。

    此外分區(qū)是由MySQL系統(tǒng)直接管理的,DBA不需要手工的去劃分和維護。例如:這個例如沒意思,不講了,如果你是DBA,只要你劃分了分區(qū),以后你就不用管了就是了。

    站在性能設(shè)計的觀點上,俺們對以上的內(nèi)容也是相當(dāng)感興趣滴。通過使用分區(qū)和對不同的SQL操作的匹配設(shè)計,數(shù)據(jù)庫的性能一定能獲得巨大提升。下面咱們一起用用這個MySQL 5.1的新功能看看。

    下面所有的測試都在Dell Optiplex box with a Pentium 4 3.00GHz processor, 1GB of RAM機器上(炫耀啊……),Fedora Core 4MySQL 5.1.6 alpha上運行通過。



    如何進行實際分區(qū)

    看看分區(qū)的實際效果吧。我們建立幾個同樣的MyISAM引擎的表,包含日期敏感的數(shù)據(jù),但只對其中一個分區(qū)。分區(qū)的表(表名為part_tab)我們采用Range范圍分區(qū)模式,通過年份進行分區(qū):

    mysql> 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 (1995),

    ??? ->????? PARTITION p1 VALUES LESS THAN (1996) , PARTITION p2 VALUES LESS THAN (1997) ,

    ??? ->????? PARTITION p3 VALUES LESS THAN (1998) , PARTITION p4 VALUES LESS THAN (1999) ,

    ??? ->????? PARTITION p5 VALUES LESS THAN (2000) , PARTITION p6 VALUES LESS THAN (2001) ,

    ??? ->????? PARTITION p7 VALUES LESS THAN (2002) , PARTITION p8 VALUES LESS THAN (2003) ,

    ??? ->????? PARTITION p9 VALUES LESS THAN (2004) , PARTITION p10 VALUES LESS THAN (2010),

    ??? ->????? PARTITION p11 VALUES LESS THAN MAXVALUE );

    Query OK, 0 rows affected (0.00 sec)

    注意到了這里的最后一行嗎?這里把不屬于前面年度劃分的年份范圍都包含了,這樣才能保證數(shù)據(jù)不會出錯,大家以后要記住啊,不然數(shù)據(jù)庫無緣無故出錯你就爽了。那下面我們建立沒有分區(qū)的表(表名為no_part_tab):

    mysql> create table no_part_tab

    ??? -> (c1 int(11) default NULL,

    ??? -> c2 varchar(30) default NULL,

    ??? -> c3 date default NULL) engine=myisam;

    Query OK, 0 rows affected (0.02 sec)

    下面咱寫一個存儲過程(感謝Peter Gulutzan給的代碼,如果大家需要Peter Gulutzan的存儲過程教程的中文翻譯也可以跟我要,chenpengyigmail.com),它能向咱剛才建立的已分區(qū)的表中平均的向每個分區(qū)插入共8百萬條不同的數(shù)據(jù)。填滿后,咱就給沒分區(qū)的克隆表中插入相同的數(shù)據(jù):

    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


    表都準(zhǔn)備好了。咱開始對這兩表中的數(shù)據(jù)進行簡單的范圍查詢吧。先分區(qū)了的,后沒分區(qū)的,跟著有執(zhí)行過程解析(MySQL Explain命令解析器),可以看到MySQL做了什么:

    mysql> select count(*) from no_part_tab where

    ??? -> c3 > date '1995-01-01' and c3 < date '1995-12-31';

    +----------+

    | count(*) |

    +----------+

    |?? 795181 |

    +----------+

    1 row in set (38.30 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 (3.88 sec)

    ?

    mysql> explain select count(*) from no_part_tab where

    ??? -> c3 > date '1995-01-01' and c3 < date '1995-12-31'\G

    *************************** 1. row ***************************

    ?????????? id: 1

    ? select_type: SIMPLE

    ??????? table: no_part_tab

    ???????? type: ALL

    possible_keys: NULL

    ????????? key: NULL

    ????? key_len: NULL

    ????????? ref: NULL

    ???????? rows: 8000000

    ??????? Extra: Using where

    1 row in set (0.00 sec)

    ?

    mysql> explain partitions select count(*) from part_tab where

    ??? -> c3 > date '1995-01-01' and c3 < date '1995-12-31'\G

    *************************** 1. row ***************************

    ?????????? 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)

    從上面結(jié)果可以容易看出,設(shè)計恰當(dāng)表分區(qū)能比非分區(qū)的減少90%的響應(yīng)時間。而命令解析Explain程序也告訴我們在對已分區(qū)的表的查詢過程中僅對第一個分區(qū)進行了掃描,其他都跳過了。

    嗶厲吧拉,說阿說……反正就是這個分區(qū)功能對DBA很有用拉,特別對VLDB和需要快速反應(yīng)的系統(tǒng)。


    Vertical Partitioning的一些看法

    雖然MySQL 5.1自動實現(xiàn)了水平分區(qū),但在設(shè)計數(shù)據(jù)庫的時候不要輕視垂直分區(qū)。雖然要手工去實現(xiàn)垂直分區(qū),但在特定場合下你會收益不少的。例如在前面建立的表中,VARCHAR字段是你平常很少引用的,那么對它進行垂直分區(qū)會不會提升速度呢?咱們看看測試結(jié)果:

    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)

    在設(shè)計上去掉了VARCHAR字段后,不止是你,俺也發(fā)現(xiàn)查詢響應(yīng)速度上獲得了另一個90%的時間節(jié)省。所以大家在設(shè)計表的時候,一定要考慮,表中的字段是否真正關(guān)聯(lián),又是否在你的查詢中有用?


    補充說明?

    這么簡單的文章肯定不能說全MySQL 5.1 分區(qū)機制的所有好處和要點(雖然對自己寫文章水平很有信心),下面就說幾個感興趣的:

    • 支持所有存儲引擎(MyISAM, Archive, InnoDB, 等等)
    • 對分區(qū)的表支持索引,包括本地索引local indexes,對其進行的是一對一的視圖鏡像,假設(shè)一個表有十個分區(qū),那么其本地索引也包含十個分區(qū)。
    • 關(guān)于分區(qū)的元數(shù)據(jù)Metadata的表可以在INFORMATION_SCHEMA數(shù)據(jù)庫中找到,表名為PARTITIONS。
    • All SHOW 命令支持返回分區(qū)表以及元數(shù)據(jù)的索引。
    • 對其操作的命令和實現(xiàn)的維護功能有(比對全表的操作還多):
      • ADD PARTITION
      • DROP PARTITION
      • COALESCE PARTITION
      • REORGANIZE PARTITION
      • ANALYZE PARTITION
      • CHECK PARTITION
      • OPTIMIZE PARTITION
      • REBUILD PARTITION
      • REPAIR PARTITION

    站在性能主導(dǎo)的觀點上來說,MySQL 5.1的分區(qū)功能能給數(shù)據(jù)性能帶來巨大的提升的同時減輕DBA的管理負擔(dān),如果分區(qū)合理的話。如果需要更多的資料可以去http://dev.mysql.com/doc/refman/5.1/en/partitioning.htmlhttp://forums.mysql.com/list.php?106獲得相關(guān)資料。

    關(guān)于MySQL分區(qū)的使用方法很快發(fā)布上來,這里有什么錯誤歡迎指出,或給我來信

    ——2006-05-05陳朋奕

    posted on 2006-05-05 14:39 benchensz 閱讀(5032) 評論(9)  編輯  收藏 所屬分類: 隨便寫寫(比較有用,值得看看)

    評論

    # re: 通過分區(qū)(Partition)提升MySQL性能[原創(chuàng)翻譯]  回復(fù)  更多評論   

    其實跟Oracle的差不多啊……
    2006-05-05 17:09 | 拉拉

    # re: 通過分區(qū)(Partition)提升MySQL性能[原創(chuàng)翻譯]  回復(fù)  更多評論   

    不錯啊,學(xué)習(xí)ing
    還不知道MySQL也能分區(qū)。
    謝了LZ
    2006-05-06 15:01 | romman

    # re: 通過分區(qū)(Partition)提升MySQL性能[原創(chuàng)翻譯]  回復(fù)  更多評論   

    如果所有分區(qū)都是在同一塊硬盤上面,性能還會有提高么?是否有評測?謝謝。
    2006-05-07 17:58 | iceboundrock

    # re: 通過分區(qū)(Partition)提升MySQL性能[原創(chuàng)翻譯]  回復(fù)  更多評論   

    看你的DBA是如何進行分區(qū)的了
    其實分區(qū)很大的目的是為了讓數(shù)據(jù)庫檢索引擎在查詢時能減少其查詢次數(shù),如果你分區(qū)合理的話,譬如使用年份進行分區(qū)其實就能讓你只查詢一部分的數(shù)據(jù)而不是全部。即使是一個硬盤上也是為有速度的提高的,如果你使用磁盤陣列當(dāng)然速度能得到更大的提升。
    2006-05-07 18:23 | chenpengyi.

    # re: 通過分區(qū)(Partition)提升MySQL性能[原創(chuàng)翻譯]  回復(fù)  更多評論   

    由于最近要用到分區(qū),所以查了一下這方面的資料,感覺樓主應(yīng)對分區(qū)有較多的了解,仔細看了一下您寫的文章,懂了不少東西,但現(xiàn)在我有一凝問,你上面舉的例子是以年來分的,查詢的條件也是年,這樣可以挑過別的分區(qū),但是我的查詢條件是某一個varchar字段,這樣會不會要全部掃描分區(qū),這樣的話,效率會提高嗎?希望樓主能回答一下
    2008-01-06 20:51 | 遠方

    # re: 通過分區(qū)(Partition)提升MySQL性能[原創(chuàng)翻譯]  回復(fù)  更多評論   

    我測試了您的數(shù)據(jù)
    在2G內(nèi)存的 HP 520筆記本上 ,ubuntu 8.04
    結(jié)果是
    分區(qū)表如果和為分區(qū)的表都在 c3上面加索引 ,則2者速度差不多

    如果no_part_tab 設(shè)置c3索引 ,而 part_tab 不設(shè)置索引,
    則 part_tab 比 no_part_tab 快1.6左右

    select count(*) from no_part_tab where c3 > date '1995-01-01' and c3 < date '1995-12-31';
    1.11秒
    select count(*) from part_tab where c3 > date '1995-01-01' and c3 < date '1995-12-31';
    0.65秒


    QQ 733905
    2009-02-05 20:23 | phpsir

    # re: 通過分區(qū)(Partition)提升MySQL性能[原創(chuàng)翻譯]  回復(fù)  更多評論   

    @遠方


    不會有提升
    2009-02-05 20:25 | phpsir

    # re: 通過分區(qū)(Partition)提升MySQL性能[原創(chuàng)翻譯]  回復(fù)  更多評論   

    @phpsir
    分區(qū),索引,其實本質(zhì)上都是為了縮小查詢范圍,但是要和WHERE條件相協(xié)調(diào)才會發(fā)生作用
    2009-07-02 12:05 | Name

    # re: 通過分區(qū)(Partition)提升MySQL性能[原創(chuàng)翻譯]  回復(fù)  更多評論   

    christian louboutin UKT555
    2010-12-31 14:15 | TT
    主站蜘蛛池模板: 亚洲一级黄色大片| 全部免费国产潢色一级| 日韩内射激情视频在线播放免费 | 亚洲国产av无码精品| 国产精品黄页在线播放免费| 成年女人毛片免费播放视频m| 成年女人喷潮毛片免费播放| 卡一卡二卡三在线入口免费| 日本视频免费在线| 日韩精品视频免费在线观看| 免费中文字幕不卡视频| 亚洲国产黄在线观看| 国产精品亚洲αv天堂无码| 久久久久亚洲精品中文字幕| 伊人久久大香线蕉亚洲| 亚洲日韩精品一区二区三区无码| 亚洲人成网站在线播放vr| 亚洲精品少妇30p| 久久久久亚洲AV无码专区首| 亚洲国产美国国产综合一区二区| 91亚洲国产在人线播放午夜| 亚洲性一级理论片在线观看| 亚洲精品第一综合99久久| 韩国亚洲伊人久久综合影院| 一边摸一边爽一边叫床免费视频| 精品乱子伦一区二区三区高清免费播放| 成人无码区免费A∨直播| 无码人妻一区二区三区免费n鬼沢 无码人妻一区二区三区免费看 | 日韩电影免费在线| 免费一级大黄特色大片| 成人午夜亚洲精品无码网站| 亚洲免费在线播放| 国产成人精品日本亚洲专区6| 亚洲av无码无线在线观看| 国产精品九九久久免费视频| 久久免费视频精品| 少妇高潮太爽了在线观看免费| 免费国产精品视频| 亚洲va久久久噜噜噜久久| 亚洲av无码专区在线| 黄页网站在线免费观看|