mysql 8.0.17 分割槽特性測試
一、下面所有的測試基於mysql 8.0.17版本。
elcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 34 Server version: 8.0.17 Source distribution Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
Server version: 8.0.17 Source distribution
編譯安裝指令碼
yum -y install gcc gcc-c++ ncurses-devel libtirpc-devel libaio-devel openssl openssl-devel 增加mysql使用者 groupadd -g 1101 mysql ; useradd -u 1101 -g mysql mysql ; mkdir -p /opt/mysql mkdir -p /data/mysqldata mkdir -p /log/mysql chown -R mysql.mysql /opt/mysql chown -R mysql.mysql /data/mysqldata chown -R mysql.mysql /log/mysql 下載mysql和rpcsvc cd /tmp wget tar zxvf rpcsvc-proto-1.4.tar.gz cd rpcsvc-proto-1.4 ./configure make make install cd /tmp wget 安裝mysql tar zxvf mysql-boost-8.0.17.tar.gz cd mysql-8.0.17 cmake -DCMAKE_INSTALL_PREFIX=/opt/mysql \ -DINSTALL_PLUGINDIR=/opt/mysql/lib/plugin \ -DMYSQL_DATADIR=/data/mysqldata \ -DWITH_MYISAM_STORAGE_ENGINE=1 \ -DWITH_INNOBASE_STORAGE_ENGINE=1 \ -DDEFAULT_CHARSET=utf8mb4 \ -DDEFAULT_COLLATION=utf8mb4_general_ci \ -DBUILD_CONFIG=mysql_release \ -DWITH_SSL=system \ -DWITH_ZLIB=system \ -DCMAKE_BUILD_TYPE=RelWithDebInfo \ -DWITH_BOOST=/tmp/mysql-8.0.17/boost/boost_1_69_0 \ -DFORCE_INSOURCE_BUILD=1 make -j 4 make install 設定配置檔案 mkdir -p /opt/mysql/etc cat >/opt/mysql/etc/my.cnf <<EOF [client] port = 3306 socket = /data/mysqldata/mysql.sock [mysqld] port = 3306 socket = /data/mysqldata/mysql.sock datadir=/data/mysqldata/ basedir=/opt/mysql mysqlx=0 #innodb innodb_data_home_dir = /data/mysqldata innodb_data_file_path = ibdata1:128M:autoextend innodb_buffer_pool_size = 1000M innodb_buffer_pool_instances=1 innodb_file_per_table=on #innodb log innodb_log_group_home_dir = /data/mysqldata innodb_log_file_size = 256M innodb_log_buffer_size = 64M innodb_log_files_in_group=4 #innodb zero data lost variables innodb_flush_log_at_trx_commit = 1 innodb_doublewrite=on sync_binlog=1 master-info-repository=table relay-log-info-repository=table #tx commit action is heavy action autocommit=on transaction_isolation=READ-COMMITTED lower_case_table_names=1 bind-address = 0.0.0.0 #character init_connect = 'SET NAMES utf8mb4' character_set_server=utf8mb4 #collation_server=utf8mb4_general_ci open_files_limit = 65535 #gtid server_id=791 gtid_mode=on enforce_gtid_consistency=on master_info_repository=table relay_log_info_repository=table #connect max_connections = 2000 max_connect_errors=9999999 #sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' #memory #query_cache_size = 0M #query_cache_type=0 #mysql log binlog_format=row log_bin = binlog log_timestamps=system log_output='file,table' log_error=/log/mysql/error.log general_log=off general_log_file=/log/mysql/general_.log relay_log = /log/mysql/mysql-relay-bin.log relay_log_purge =off max_binlog_size = 256M log_slave_updates=on binlog_expire_logs_seconds = 604800 slow_query_log_file=/log/mysql/slow.log slow_query_log=on long_query_time=1 skip_name_resolve=on #slave #skip_slave_start slave-skip-errors=1062 replicate_ignore_db=mysql replicate_wild_ignore_table=mysql.% #resource max_allowed_packet = 128M innodb_lock_wait_timeout = 50 #use audit binlog_rows_query_log_events=on EOF 修改目錄許可權和初始化mysql chown -R mysql.mysql /opt/mysql chown -R mysql.mysql /data/mysqldata chown -R mysql.mysql /log/mysql /opt/mysql/bin/mysqld --defaults-file=/opt/mysql/etc/my.cnf --initialize --user=mysql 將mysql設定為開機自動啟動 cp /opt/mysql/support-files/mysql.server /etc/init.d/mysqld chmod +x /etc/init.d/mysqld systemctl enable mysqld.service #chkconfig --add mysqld 重啟mysql systemctl restart mysqld.service
二、總體感受:
使用了mysql的分割槽,覺得最不爽的是mysql partition 限制:
A UNIQUE INDEX must include all columns in the table's partitioning function
A PRIMARY KEY must include all columns in the table's partitioning function
意思就是:用於分割槽的column 必須是主鍵列,或者主鍵的其中幾個列,或者是唯一鍵列。無論建立何種型別的分割槽,如果表中存在主鍵或唯一索引時,分割槽列必須是唯一索引的一個組成部分。也不清楚作者這樣設計的初衷是什麼。比如以下的寫法就是有語法錯誤:
CREATE TABLE t1 ( col1 INT NOT NULL, col2 DATE NOT NULL, col3 INT NOT NULL, col4 INT NOT NULL, UNIQUE KEY (col1, col2) ) PARTITION BY HASH(col3) PARTITIONS 4; CREATE TABLE t2 ( col1 INT NOT NULL, col2 DATE NOT NULL, col3 INT NOT NULL, col4 INT NOT NULL, UNIQUE KEY (col1), UNIQUE KEY (col3) ) PARTITION BY HASH(col1 + col3) PARTITIONS 4;
這樣會大大限制mysql分割槽使用範圍。
三、mysql 分割槽的種類
1.range 分割槽,頻繁使用。 基於屬於一個給定連續區間的列值,把多行分配給分割槽。
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) );
2. list 分割槽,比較少使用。類似於按RANGE分割槽,區別在於LIST分割槽是基於列值匹配一個離散值集合中的某個值來進行選擇。
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 LIST(store_id) ( PARTITION pNorth VALUES IN (3,5,6,9,17), PARTITION pEast VALUES IN (1,2,10,11,19,20), PARTITION pWest VALUES IN (4,12,13,14,18), PARTITION pCentral VALUES IN (7,8,15,16) );
注意看上面,都是沒有主鍵,沒有唯一鍵的。
3.HASH分割槽,頻繁使用:基於使用者定義的表示式的返回值來進行選擇的分割槽,該表示式使用將要插入到表中的這些行的列值進行計算。這個函式可以包含MySQL 中有效的、產生非負整數值的任何表示式。
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( YEAR(hired) ) PARTITIONS 4;
4.KEY分割槽:類似於按HASH分割槽,區別在於KEY分割槽只支援計算一列或多列,且MySQL伺服器提供其自身的雜湊函式。必須有一列或多列包含整數值。
CREATE TABLE k1 ( id INT NOT NULL PRIMARY KEY, name VARCHAR(20) ) PARTITION BY KEY() PARTITIONS 2; CREATE TABLE k1 ( id INT NOT NULL, name VARCHAR(20), UNIQUE KEY (id) )PARTITION BY KEY() PARTITIONS 2;
上面兩個例子你會覺得很奇怪,都沒有指定分割槽列。mysql預設就使用了唯一鍵來做了分割槽。
四、表分割槽的優點
1)當資料量很大(過T)時,肯定不能把資料再如到記憶體中,這樣查詢一個或一定範圍的item是很耗時。另外一般這情況下,歷史資料或不常訪問的資料佔很大部分,最新或熱點資料佔的比例不是很大。這時可以根據有些條件進行表分割槽。
2)分割槽表的更易管理,比如刪除過去某一時間的歷史資料,直接執行truncate,或者狠點drop整個分割槽,這比detele刪除效率更高
3)當資料量很大,或者將來很大的,但單塊磁碟的容量不夠,或者想提升IO效率的時候,可以把沒分割槽中的子分割槽掛載到不同的磁碟上。
4)使用分割槽表可避免某些特殊的瓶頸,例如Innodb的單個索引的互斥訪問..
5)單個分割槽表的備份很恢復會更有效率,在某些場景下
6)涉及到例如SUM()和COUNT()這樣聚合函式的查詢,可以很容易地進行並行處理。
這種查詢的一個簡單例子如
“SELECT salesperson_id, COUNT (orders) as order_total FROM sales GROUP BY salesperson_id;”。
透過“並行”,這意味著該查詢可以在每個分割槽上同時進行,最終結果只需透過總計所有分割槽得到的結果。
五、表分割槽的查詢最佳化
表分割槽了,查詢where必須帶上分割槽鍵,否則使用不到分割槽的好處了。我們來看下例子:
CREATE TABLE part_tab (c1 int default NULL, c2 varchar(30) default NULL, c3 date not null) 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) ); CREATE TABLE no_part_tab(c1 int default NULL, c2 varchar(30) default NULL, c3 date not null); drop procedure load_part_tab; delimiter $$ CREATE PROCEDURE load_part_tab() begin declare v int default 0; while v < 8000000 do insert into part_tab values (v,'testingpartitions',adddate('1995-01-01',(rand(v)*36520)mod 3652)); set v = v + 1; end while; end;$$ delimiter ; call load_part_tab(); //從 part_tab 匯入資料到 no_part_tab insert into no_part_tab select * from part_tab;
建立了2個表,資料都是800萬。
一個表no_part_tab的大小是428M。在這裡另外
mysql> explain select count(*) from part_tab where c3 > date '1995-01-01'and c3 < date '1995-12-31'; +----+-------------+----------+------------+------+---------------+------+---------+------+--------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+----------+------------+------+---------------+------+---------+------+--------+----------+-------------+ | 1 | SIMPLE | part_tab | p1 | ALL | NULL | NULL | NULL | NULL | 796215 | 11.11 | Using where | +----+-------------+----------+------------+------+---------------+------+---------+------+--------+----------+-------------+ 1 row in set, 1 warning (0.00 sec) mysql> explain select count(*) from no_part_tab where c3 > date '1995-01-01'and c3 < date '1995-12-31'; +----+-------------+-------------+------------+------+---------------+------+---------+------+---------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------------+------------+------+---------------+------+---------+------+---------+----------+-------------+ | 1 | SIMPLE | no_part_tab | NULL | ALL | NULL | NULL | NULL | NULL | 7773613 | 11.11 | Using where | +----+-------------+-------------+------------+------+---------------+------+---------+------+---------+----------+-------------+ 1 row in set, 1 warning (0.01 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.39 sec) 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 (2.94 sec)
查詢時間和掃描的行數,高下可判。
六、mysql分割槽操作,在mysql8測試透過
序號 | 常見操作 | 舉例 | 備註 |
1 | 刪除分割槽 | 1) aher table emp drop partition p1;
2) 一次性刪除各個區:alter table emp drop partition p1,p2; 3) 刪除表的所有分割槽:Alter table emp remove partitioning; |
1)不可以刪除hash或者kev分割槽。
2)刪除分割槽會刪除資料,但是刪除表的所有分割槽--不會丟失資料(驗證ok) |
2 | 增加分割槽 | alter table emp add partition (partition p1 values less than (24));
alter table emp add partition partition p3 values in (40)); |
1)增加分割槽的值只能增加,不能比現在所擁有的分割槽值低 |
3 | 分解分割槽 | alter table emp reorganize partition p2 into
(partition p1 values less than (6), partition p2 values less than (16)); |
reorganize partition關鍵字可以對錶的部分分割槽或全部分割槽進行修
改,並且不會丟失資料。分解前後分割槽的整體範圍應該一致。 |
4 | 合併分割槽 | alter table emp reorganize partition p1,p3 into (partition p1 values less than (1000)); | 不會丟失資料 |
5 | 重新定義分割槽 | 重新定義Hash分割槽:Alter table emp partition by hash(salary) partitions 7;
重新定義Range分割槽: Alter table emp partition by range(id) (partition p1 values less than (2000), partition p2 values less than (4000)); |
相當於刪除重建。 |
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/30393770/viewspace-2660571/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- mysql~關於mysql分割槽表的測試MySql
- MySQL 8部分新特性(8.0.17)MySql
- oracle partition分割槽_分割槽列為空測試(一)Oracle
- 表分割槽機制測試
- 測試oracle子分割槽維護Oracle
- Hash分割槽表分割槽數與資料分佈的測試
- mysql 分割槽MySql
- MySQL分割槽MySql
- 理解MySQL分割槽MySql
- 搞懂MySQL分割槽MySql
- 【MYSQL】 分割槽表MySql
- MySql建立分割槽MySql
- MySQL 子分割槽MySql
- MySQL KEY分割槽MySql
- MySQL HASH分割槽MySql
- MySQL COLUMNS分割槽MySql
- MySQL LIST分割槽MySql
- MySQL RANGE分割槽MySql
- MySQL 分割槽表MySql
- MySQL分割槽表MySql
- mysql分割槽nullMySqlNull
- mysql 分割槽示例MySql
- oracle分割槽表的分類及測試Oracle
- MySql資料分割槽操作之新增分割槽操作MySql
- MySQL 分割槽表 partition線上修改分割槽欄位MySql
- 【ORACLE新特性】11G 分割槽新特性Oracle
- MySQL的分割槽(一)MySql
- MySQL的分割槽(二)MySql
- MySQL 分割槽表探索MySql
- mysql 分表 分割槽MySql
- MySQL分割槽學習MySql
- MySQL 分割槽建索引MySql索引
- MySQL分割槽介紹MySql
- mysql 分割槽表用法MySql
- MySQL表分割槽管理MySql
- postgresql 9.6 分割槽表測試方案與記錄SQL
- Oracle 11g 雜湊、LIST分割槽測試Oracle
- oracle 並行cpu查詢分割槽表測試Oracle並行