理解MySQL——並行數據庫與分區(Partition)

一、並行數據庫 html

 

1.一、並行數據庫的體系結構
並行機的出現,催生了並行數據庫的出現,不對,應該是關係運算原本就是高度可並行的。對數據庫系統性能的度量主要有兩種方式:(1)吞吐量(Throughput),在給定的時間段裏所能完成的任務數量;(2)響應時間(Response time),單個任務從提交到完成所須要的時間。對於處理大量小事務的系統,經過並行地處理許多事務能夠提升它的吞吐量。對於處理大事務的系統,經過並行的執行事務的子任務,能夠縮短系統晌應時間。
並行機有三種基本的體系結構,相應的,並行數據庫的體系結構也能夠大概分爲三類:
    共享內存(share memeory):全部處理器共享一個公共的存儲器;
    共享磁盤(share disk):全部處理器共享公共的磁盤;這種結構有時又叫作集羣(cluster);
    無共享(share nothing):全部處理器既不共享內存,也不共享磁盤。
如圖所示:

1.1.一、    共享內存
該結構包括多個處理器、一個全局共享的內存(主存儲器)和多個磁盤存儲,各個處理器經過高速通信網絡(Interconnection Network)與共享內存鏈接,並都可直接訪問系統中的一個、多個或所有的磁盤存儲,在系統中,全部的內存和磁盤存儲均由多個處理器共享。
這種結構的優勢在於,處理器之間的通訊效率極高,訪問內存的速度要比消息通訊機制要快不少。這種結構的缺點在於,處理器的規模不能超過32個或者64個,由於總線或互邊網絡是由全部的處理器共享,它會變成瓶頸。當處理器數量到達某一個點時,再增長處理器已經沒有什麼好處。
共享內存結構一般在每一個處理器上有很大的高速緩存,從而減小對內存的訪問。可是,這些高速緩存必須保持一致,也就是緩存一致性(cache-coherency)的問題。
1.1.二、    共享磁盤
該結構由多個具備獨立內存(主存儲器)的處理器和多個磁盤存儲構成,各個處理器相互之間沒有任何直接的信息和數據的交換,多個處理器和磁盤存儲由高速通訊網絡鏈接,每一個處理器均可以讀寫所有的磁盤存儲。
共享磁盤與共享內存結構相比,有如下一些優勢:(1)每一個處理器都有本身的存儲器,存儲總線再也不是瓶頸;(2)以一種較經濟的方式提供了容錯性(fault tolerence),若是一個處器發生故障,其它處理器能夠代替工做。
該結構的主要問題不是在於可擴展性問題,雖然存儲總線不是瓶頸,可是,與磁盤之間的鏈接又成了瓶頸。
運行Rdb的DEC集羣是共享磁盤的體系結構的早期商用化產品之一(DEC後來被Compaq公司收購,再後來,Oracle又從Compaq手中取得Rdb,發展成如今的Oracle RAC)。
1.1.三、    無共享
該結構由多個徹底獨立的處理節點構成,每一個處理節點具備本身獨立的處理器、獨立的內存(主存儲器)和獨立的磁盤存儲,多個處理節點在處理器級由高速通訊網絡鏈接,系統中的各個處理器使用本身的內存獨立地處理本身的數據。
這 種結構中,每個處理節點就是一個小型的數據庫系統,多個節點一塊兒構成整個的分佈式的並行數據庫系統。因爲每一個處理器使用本身的資源處理本身的數據,不存 在內存和磁盤的爭用,提升的總體性能。另外這種結構具備優良的可擴展性——只需增長額外的處理節點,就能夠以接近線性的比例增長系統的處理能力。
    這種結構中,因爲數據是各個處理器私有的,所以系統中數據的分佈就須要特殊的處理,以儘可能保證系統中各個節點的負載基本平衡,但在目前的數據庫領域,這個數據分佈問題已經有比較合理的解決方案。
因爲數據是分佈在各個處理節點上的,所以,使用這種結構的並行數據庫系統,在擴展時不可避免地會致使數據在整個系統範圍內的重分佈(Re-Distribution)問題。
    Shared-Nothing結構的典型表明是Teradata(並行數據庫的先驅),值得一提的是,MySQL NDB Cluster也使用了這種結構。

 1.二、I/O並行(I/O Parallelism)
I/O並行的最簡單形式是經過對關係劃分,放置到多個磁盤上來縮減從磁盤讀取關係的時間。並行數據庫中數據劃分最通用的形式是水平劃分(horizontal portioning),一個關係中的元組被劃分到多個磁盤。
1.2.一、經常使用劃分技術
假定將數據劃分到n個磁盤D0,D1,…,Dn中。
(1)    輪轉法(round-bin)。對關係順序掃描,將第i個元組存儲到標號爲Di%n的磁盤上;該方式保證了元組在多個磁盤上均勻分佈。
(2)    散列劃分(hash partion)。選定一個值域爲{0, 1, …,n-1}的散列函數,對關係中的元組基於劃分屬性進行散列。若是散列函數返回i,則將其存儲到第i個磁盤。
(3)    範圍劃分(range partion)。
因爲將關係存儲到多個磁盤,讀寫時能同時進行,劃分(partion)能大大提升系統的讀寫性能。數據的存取能夠分爲如下幾類:
(1)    掃描整個關係;
(2)    點查詢(point query),如name = 「hustcat」;
(3)    範圍查詢(range query),如 20 < age < 30。
不一樣的劃分技術,對這些存取類型的效率是不一樣的:
    輪轉法適合順序掃描關係,對點查詢和範圍查詢的處理較複雜。
    散列劃分特別適合點查詢,速度最快。
    範圍劃分對點查詢、範圍查詢以及順序掃描都支持較好,因此適用性很廣。可是,這種方式存在一個問題——執行偏斜(execution skew),也就是說某些範圍的元組較多,使得大量的I/O出如今某幾個磁盤。 mysql

1.三、查詢間並行(interquery parallism)
查詢間並行指的是不一樣的查詢或事務間並行的執行。這種形式的並行能夠提升事務的吞吐量,然而,單個事務並不能執行得更快(即響應時間不能減小)。查詢間的並行主要用於擴展事務處理系統,在單位時間內可以處理更多的事務。
查詢間並行是數據庫系統最易實現的一種並行,在共享內存的並行系統(如SMP)中尤爲這樣。爲單處理器設計的數據庫系統能夠不用修改,或者不多修改就能用到共享內存的體系結構。
在共享磁盤和無共享的體系結構中,實現查詢間並行要更復雜一些。各個處理須要協調來進行封鎖、日誌操做等等,這就須要處理器之間的傳遞消息。並行數據庫系統必須保證兩個處理器不會同時更新同一數據。並且,處理器訪問數據時,系統必須保證處理器緩存的數據是最新的數據,即緩存一致性問題。

1.四、查詢內並行(intraquery parallism)
查詢內並行是指單個查詢要在多個處理器和磁盤上同時進行。爲了理解,來考慮一個對某關係進行排序的查詢。假設關係已經基於某個屬性進行了範圍劃分,存儲於多個磁盤上,而且劃分是基於劃分屬性的。則排序操做能夠以下進行:對每一個分區並行的排序,而後將各個已經有序的分區合併到一塊兒。
單個查詢的執行能夠有兩種並行方式:
(1)    操做內並行(Intraoperation parallism):經過並行的執行每個運算,如排序、選擇、鏈接等,來加快一個查詢的處理速度。
(2)    操做間並行(Interoperation parallism):經過並行的執行一個查詢中的多個不一樣的運算,來加速度一個查詢的處理速度。
注意二者間的區別,前者能夠認爲多個處理器同時執行一個運算,然後者是多個處理器同時執行不一樣的運算。
這兩種形式之間的並行是互相補充的,而且能夠同時存在於一個查詢中。一般因爲一個查詢中的運算數目相對於元組數目是較小的,因此當並行度增長時,第一種方式取得的效果更顯著。

二、MySQL的分區(partion)
2.一、MySQL分區概述
在MySQL中,InnoDB存儲引擎長期支持表空間的概念,而且MySQL服務器甚至在分區引入以前,就能配置爲存儲不一樣的數據庫使用不一樣的物理路徑。分區(partion)更進一步,它容許你經過設置各類規則將一個表的各個分區跨文件系統存儲。實際上,不一樣位置的不一樣表分區是做爲一個單獨的表來存儲的。用戶所選擇的、實現數據分割的規則被稱爲分區函數(partioning function),這在MySQL中它能夠是模數,或者是簡單的匹配一個連續的數值區間或數值列表,或者是一個內部HASH函數,或一個線性HASH函數。
    最多見是的水平分區(horizontal partitioning),也就是將表的不一樣的元組分配到不一樣的物理分區上。目前,MySQL 5.1還不支持垂直分區(vertical partitioning),即將表的不一樣列分配到不一樣的物理分區。你可使用MySQL支持的大多數存儲引擎來建立表的分區,在MySQL 5.1中,同一個表的各個分區必須使用相同的存儲引擎,好比,你不能對一個分區使用MyISAM,而對另外一個分區使用InnoDB。可是,你能夠對同一個數據庫的不一樣的表使用不一樣的存儲引擎。
    要爲某個分區表配置一個專門的存儲引擎,必須且只能使用[STORAGE] ENGINE 選項,這如同爲非分區表配置存儲引擎同樣。可是,必須記住[STORAGE] ENGINE(和其餘的表選項)必須列在用在CREATE TABLE語句中的其餘任何分區選項以前。下面的例子給出了怎樣建立一個經過HASH分紅6個分區、使用InnoDB存儲引擎的表: sql

CREATE TABLE ti (id INT, amount DECIMAL(7,2), tr_date DATE) 數據庫

    ENGINE=INNODB 緩存

    PARTITION BY HASH( MONTH(tr_date) ) 服務器

    PARTITIONS 6; 網絡

注:分區必須對一個表的全部數據和索引;不能只對數據分區而不對索引分區,反之亦然,同時也不能只對表的一部分進行分區。
    分區對數據庫管理系統實現並行處理有着重要的影響,若是對數據進行分區,則很容易進行並行處理,可是,MySQL尚未充分利用分區的這種並行優點,而這也是它改進的方向 (這種分治思想深深的影響着並行計算,並且在並行計算方面具備自然優點)。MySQL的分區,會給系統帶來如下一些優勢:
    與單個磁盤或文件系統分區相比,單個表能夠存儲更多的數據。
    對於那些已經失去保存意義的數據,一般能夠經過刪除與那些數據有關的分區,很容易地刪除那些數據。相反地,在某些狀況下,添加新數據的過程又能夠經過爲那些新數據專門增長一個新的分區,來很方便地實現。
    對於帶Where的條件查詢語句,能夠獲得更大的優化;只須要查詢某些分區,而不用掃描所有分區。
還有其它一些優勢,不過MySQL 5.1還不支持:
    一些聚合函數,好比SUM() 和COUNT(),可以很容易的並行執行;
    經過並行I/O,能夠大大提升查詢的吞吐量。
注:實際上,分區不管是對I/O並行,仍是查詢內並行,都有着重要的影響。只不過MySQL在這方面作得還不夠多(不過,正在改進),而Oracle對於查詢內並行,作了不少工做。

2.二、分區類型
MySQL 5.1中可用的分區類型包括:
    RANGE分區(portioning):根據列值所屬的範圍區間,將元組分配到各個分區。
    LIST分區:相似於按RANGE分區,區別在於LIST分區是基於列值匹配一個離散值集合中的某個值來進行選擇。
    HASH分區:根據用戶定義的函數的返回值來進行選擇的分區,該表達式使用將要插入到表中的這些行的列值進行計算。這個函數能夠包含MySQL 中有效的、產生非負整數值的任何表達式。
    KEY分區:相似於按HASH分區,區別在於KEY分區只支持計算一列或多列,且MySQL 服務器提供其自身的哈希函數。
2.2.一、範圍分區
範圍分區是經過計算表達式的值所屬的範圍區間,對元組進行分區。這些區間要求連續且不能相互重疊,使用VALUES LESS THAN操做符來進行定義。在下面的幾個例子中,假定你建立了一個以下的一個表,該表保存有20家音像店的職員記錄,這20家音像店的編號從1到20。 分佈式

CREATE TABLE employees ( ide

    id INT NOT NULL, 函數

    fname VARCHAR(30),

    lname VARCHAR(30),

    hired DATE NOT NULL DEFAULT '1970-01-01',

    separated DATE NOT NULL DEFAULT '9999-12-31',

    job_code INT NOT NULL,

    store_id INT NOT NULL

);

你能夠根據須要對該表進行各類分區,好比,你能夠經過store_id來進行分區:

CREATE TABLE employees (

    id INT NOT NULL,

    fname VARCHAR(30),

    lname VARCHAR(30),

    hired DATE NOT NULL DEFAULT '1970-01-01',

    separated DATE NOT NULL DEFAULT '9999-12-31',

    job_code INT NOT NULL,

    store_id INT NOT NULL

)

PARTITION BY RANGE (store_id) (

    PARTITION p0 VALUES LESS THAN (6),

    PARTITION p1 VALUES LESS THAN (11),

    PARTITION p2 VALUES LESS THAN (16),

    PARTITION p3 VALUES LESS THAN (21)

);

很容易肯定數據(72, 'Michael', 'Widenius', '1998-06-25', NULL, 13)被插入分區p2;可是,若是一條數據的store_id = 21,會怎麼樣呢?因爲沒有規則處理大於20的狀況,因此服務器會報錯。你能夠經過以下方式來處理這種狀況:

CREATE TABLE employees (

    id INT NOT NULL,

    fname VARCHAR(30),

   lname VARCHAR(30),

    hired DATE NOT NULL DEFAULT '1970-01-01',

    separated DATE NOT NULL DEFAULT '9999-12-31',

    job_code INT NOT NULL,

    store_id INT NOT NULL

)

PARTITION BY RANGE (store_id) (

    PARTITION p0 VALUES LESS THAN (6),

    PARTITION p1 VALUES LESS THAN (11),

    PARTITION p2 VALUES LESS THAN (16),

    PARTITION p3 VALUES LESS THAN MAXVALUE

);

MAXVALUE 表示最大的可能的整數值。如今,store_id 列值大於或等於16(定義了的最高值)的全部行都將保存在分區p3中。在未來的某個時候,當商店數已經增加到25, 30, 或更多 ,可使用ALTER TABLE語句爲商店21-25, 26-30,等等增長新的分區
RANGE分區在以下場合特別有用:
(1)    當須要刪除「舊的」數據時。 在上面的例子中,你只需簡單地使用 「ALTER TABLE employees DROP PARTITION p0;」來刪除全部在1991年前就已經中止工做的僱員相對應的全部行。對於有大量行的表,這比運行一個如「DELETE FROM employees WHERE YEAR(separated) <= 1990;」這樣的一個DELETE查詢要有效得多。
(2)    常常依賴於分區屬性進行查詢。例如,當執行一個如「SELECT COUNT(*) FROM employees WHERE YEAR(separated) = 2000 GROUP BY store_id;」這樣的查詢時,MySQL能夠很迅速地肯定只有分區p2須要掃描,這是由於餘下的分區不可能包含有符合該WHERE子句的任何記錄。注:這種優化尚未在MySQL 5.1源程序中啓用,可是,有關工做正在進行中。
範圍分區的缺點就是容易出現執行偏斜,這會影響系統性能。
2.2.二、HASH分區
HASH分區主要用來確保數據在預先肯定數目的分區中平均分佈。在RANGE和LIST分區中,必須明確指定一個給定的列值或列值集合應該保存在哪一個分區中;而在HASH分區中,MySQL 自動完成這些工做,你所要作的只是基於將要被哈希的列值指定一個列值或表達式,以及指定被分區的表將要被分割成的分區數量。
你能夠經過要在CREATE TABLE 語句上添加一個「PARTITION BY HASH (expr)」子句,其中「expr」是一個返回一個整數的表達式。它能夠僅僅是字段類型爲MySQL 整型的一列的名字。此外,你極可能須要在後面再添加一個「PARTITIONS num」子句,其中num 是一個非負的整數,它表示表將要被分割成分區的數量。好比:

CREATE TABLE employees (

    id INT NOT NULL,

    fname VARCHAR(30),

    lname VARCHAR(30),

    hired DATE NOT NULL DEFAULT '1970-01-01',

    separated DATE NOT NULL DEFAULT '9999-12-31',

    job_code INT,

    store_id INT

)

PARTITION BY HASH(store_id)

PARTITIONS 4;

若是沒有PARTITIONS語句,默認分區數爲1。可是,PARTITIONS後面沒有數字,系統會報錯。
相對於範圍分區,HASH分區更可能保證數據均衡分佈。
2.2.三、子分區(Subpartitioning)
子分區,也叫作複合分區(composite partitioning),是對分區表的每一個分區的進一步分割。例如,

CREATE TABLE ts (id INT, purchased DATE)

    PARTITION BY RANGE( YEAR(purchased) )

    SUBPARTITION BY HASH( TO_DAYS(purchased) )

    SUBPARTITIONS 2 (

        PARTITION p0 VALUES LESS THAN (1990),

        PARTITION p1 VALUES LESS THAN (2000),

        PARTITION p2 VALUES LESS THAN MAXVALUE

    );

表ts 有3個RANGE分區。這3個分區中的每個分區——p0, p1, 和 p2 ——又被進一步分紅了2個子分區。實際上,整個表被分紅了3 * 2 = 6個分區。可是,因爲PARTITION BY RANGE子句的做用,這些分區的頭2個只保存「purchased」列中值小於1990的那些記錄。
在MySQL 5.1中,對於已經經過RANGE或LIST分區了的表再進行分區。子分區既可使用HASH希分區,也可使用KEY分區。
爲了對個別的子分區指定選項,使用SUBPARTITION  子句來明肯定義子分區也是可能的。例如,建立在前面例子中給出的同一個表的、一個更加詳細的方式以下:

CREATE TABLE ts (id INT, purchased DATE)

    PARTITION BY RANGE( YEAR(purchased) )

    SUBPARTITION BY HASH( TO_DAYS(purchased) ) (

        PARTITION p0 VALUES LESS THAN (1990) (

            SUBPARTITION s0,

            SUBPARTITION s1

        ),

        PARTITION p1 VALUES LESS THAN (2000) (

            SUBPARTITION s2,

            SUBPARTITION s3

        ),

        PARTITION p2 VALUES LESS THAN MAXVALUE (

            SUBPARTITION s4,

            SUBPARTITION s5

        )

    );

一些注意點:
(1)    每一個分區的子分區數必須相同;
(2)    若是在一個分區表上的任何分區上使用SUBPARTITION 來明肯定義任何子分區,那麼就必須定義全部的子分區;
(3)    每一個SUBPARTITION子句必須包含一個子分區的名稱;
(4)    MySQL 5.1.7及以前的版本,每一個分區的子分區的名稱必須惟一,可是在整個表中,沒有必要惟一。從MySQL 5.1.8開始,子分區的名稱在整個表中都必須惟一。
子分區能夠用於特別大的表,在多個磁盤間分配數據和索引。假設有6個磁盤,分別爲/disk0, /disk1, /disk2等,對於以下例子:

CREATE TABLE ts (id INT, purchased DATE)

    PARTITION BY RANGE( YEAR(purchased) )

    SUBPARTITION BY HASH( TO_DAYS(purchased) ) (

        PARTITION p0 VALUES LESS THAN (1990) (

            SUBPARTITION s0

                DATA DIRECTORY = '/disk0/data'

                INDEX DIRECTORY = '/disk0/idx',

            SUBPARTITION s1

                DATA DIRECTORY = '/disk1/data'

                INDEX DIRECTORY = '/disk1/idx'

        ),

        PARTITION p1 VALUES LESS THAN (2000) (

            SUBPARTITION s2

                DATA DIRECTORY = '/disk2/data'

                INDEX DIRECTORY = '/disk2/idx',

            SUBPARTITION s3

                DATA DIRECTORY = '/disk3/data'

                INDEX DIRECTORY = '/disk3/idx'

        ),

        PARTITION p2 VALUES LESS THAN MAXVALUE (

            SUBPARTITION s4

                DATA DIRECTORY = '/disk4/data'

                INDEX DIRECTORY = '/disk4/idx',

            SUBPARTITION s5

                DATA DIRECTORY = '/disk5/data'

                INDEX DIRECTORY = '/disk5/idx'

        )

    );


三、體驗分區
下面經過例子來體驗分區:
(1)建立以下分區表:

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

(2)建立一個不分區的表:

create table no_part_tab

(c1 int(11) default NULL,

c2 varchar(30) default NULL,

c3 date default NULL

) engine=myisam;

(1)    建立一個生成8000000行數據的存儲過程:

delimiter //

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

 //

(2)    調用存儲過程,生成數據:

mysql> delimiter ;

mysql> call load_part_tab();

Query OK, 1 row affected (6 min 35.39 sec)

(5)

mysql> insert into no_part_tab select * from part_tab;

Query OK, 8000000 rows affected (40.98 sec)

Records: 8000000 Duplicates: 0 Warnings: 0

 

數據準備好了,下面開始測試:

(6)

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 (4.23 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.55 sec)

速度差別很明顯;下面看一下查詢計劃:

(8)

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: 8000000  #why??
        Extra: Using where
1 row in set (0.00 sec)

 


附SQL語句:

 1  CREATE   TABLE  part_tab
 2  (  c1  int   default   NULL ,
 3  c2  varchar ( 30 default   NULL ,
 4  c3 date  default   NULL
 5  ) engine = myisam
 6  PARTITION  BY  RANGE ( year (c3)) 
 7  (
 8  PARTITION p0  VALUES  LESS THAN ( 1995 ),
 9  PARTITION p1  VALUES  LESS THAN ( 1996 ) , 
10  PARTITION p2  VALUES  LESS THAN ( 1997 ) ,
11  PARTITION p3  VALUES  LESS THAN ( 1998 ) ,
12  PARTITION p4  VALUES  LESS THAN ( 1999 ),
13  PARTITION p5  VALUES  LESS THAN ( 2000 ) , 
14  PARTITION p6  VALUES  LESS THAN ( 2001 ) ,
15  PARTITION p7  VALUES  LESS THAN ( 2002 ) , 
16  PARTITION p8  VALUES  LESS THAN ( 2003 ) ,
17  PARTITION p9  VALUES  LESS THAN ( 2004 ) , 
18  PARTITION p10  VALUES  LESS THAN ( 2010 ),
19  PARTITION p11  VALUES  LESS THAN MAXVALUE 
20  );
21 
22 
23  create   table  no_part_tab
24  (c1  int ( 11 default   NULL ,
25  c2  varchar ( 30 default   NULL ,
26  c3 date  default   NULL
27  ) engine = myisam;
28 
29 
30  delimiter  //
31  CREATE   PROCEDURE  load_part_tab()
32  begin
33  declare  v  int   default   0 ;
34             while  v  <   8000000
35    do
36     insert   into  part_tab(c1,c2,c3)
37     values  (v, ' testing partitions ' ,adddate( ' 1995-01-01 ' ,( rand (v) * 36520 ) mod  3652 ));
38     set  v  =  v  +   1 ;
39     end   while ;
40     end
41  //
42 
43  delimiter ;
44  call load_part_tab();
45  explain  select   count ( * from  no_part_tab  where
46  c3  >  date  ' 1995-01-01 '   and  c3  <  date  ' 1995-12-31 ' ;
47 
48  explain  select   count ( * from  part_tab  where
49  c3  >  date  ' 1995-01-01 '   and  c3  <  date  ' 1995-12-31 ' ;
50 
51 
52 
53 
54  CREATE   TABLE  part_tab2
55  (  
56  c1  int   default   NULL
57  ) engine = myisam
58  PARTITION  BY  RANGE (c1) 
59  (
60  PARTITION p0  VALUES  LESS THAN ( 5 ),
61  PARTITION p1  VALUES  LESS THAN ( 10 ),
62  PARTITION p2  VALUES  LESS THAN MAXVALUE
63  );
64 
65  insert   into  part_tab2  values ( 2 ),( 3 );
複製代碼

相關文章
相關標籤/搜索