mysql8.0 分區表查詢性能調查


mysql8.0 分區表查詢性能調查

測試環境

  • vmware CentOS Linux release 7.8.2003 (Core) 64位
  • 2處理器,2G
  • mysq l8.0.23

創建表

14個分區,每個分區400W數據,共5600W數據。

CREATE TABLE bdm_range_datetime(
	`id` BIGINT NOT NULL AUTO_INCREMENT,
    hiredate DATETIME,
    user_name varhcar(64),
   PRIMARY KEY (`id`,hiredate) 
)
PARTITION BY RANGE (TO_DAYS(hiredate) ) (
    PARTITION p1 VALUES LESS THAN ( TO_DAYS('20200101') ),
    PARTITION p2 VALUES LESS THAN ( TO_DAYS('20200201') ),
    PARTITION p3 VALUES LESS THAN ( TO_DAYS('20200301') ),
    PARTITION p4 VALUES LESS THAN ( TO_DAYS('20200401') ),
    PARTITION p5 VALUES LESS THAN ( TO_DAYS('20200501') ),
    PARTITION p6 VALUES LESS THAN ( TO_DAYS('20200601') ),
    PARTITION p7 VALUES LESS THAN ( TO_DAYS('20200701') ),
    PARTITION p8 VALUES LESS THAN ( TO_DAYS('20200801') ),
    PARTITION p9 VALUES LESS THAN ( TO_DAYS('20200901') ),
    PARTITION p10 VALUES LESS THAN ( TO_DAYS('20201001') ),
	PARTITION p11 VALUES LESS THAN ( TO_DAYS('20201101') ),
	PARTITION p12 VALUES LESS THAN ( TO_DAYS('20201201') ),
	PARTITION p13 VALUES LESS THAN ( TO_DAYS('20210101') ),
	PARTITION p14 VALUES LESS THAN ( TO_DAYS('20210201') )
);

數據初始化

CREATE DEFINER=`root`@`%` PROCEDURE `test_insert`(IN `hiredate` INT)
	LANGUAGE SQL
	NOT DETERMINISTIC
	CONTAINS SQL
	SQL SECURITY DEFINER
	COMMENT ''
BEGIN
DECLARE y INT DEFAULT 1;
WHILE y<40000
DO
INSERT INTO bdm_range_datetime(`hiredate`,`user_name`) VALUES 
(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),
(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),
(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),
(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),
(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),
(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),
(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),
(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),
(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),
(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1),(hiredate,LAST_INSERT_ID()+1);
SET y=y+1;
END WHILE ;
commit;
END

調用:

call test_insert(20191231);
call test_insert(20200101);
call test_insert(20200201);
call test_insert(20200301);
call test_insert(20200401);
call test_insert(20200501);
call test_insert(20200601);
call test_insert(20200701);
call test_insert(20200801);
call test_insert(20200901);
call test_insert(20201001);
call test_insert(20201101);
call test_insert(20201201);
call test_insert(20210101);

執行情況

PRIMARY KEY (`id`,hiredate) 組合主鍵

1個分區執行時間- PRIMARY KEY (`id`,hiredate) 組合主鍵

一個分區查詢
select count(*) from bdm_range_datetime where hiredate='2019-12-31' ;
/* Affected rows: 0  已找到記錄: 1  警告: 0  持續時間 1 query: 0.734 sec. */

索引全分區查詢
select * from bdm_range_datetime1 where id=300
/* Affected rows: 0  已找到記錄: 1  警告: 0  持續時間 1 query: 0.015 sec. */

索引id查詢
select * from bdm_range_datetime1 where id=300 and hiredate='2019-12-31'
/* Affected rows: 0  已找到記錄: 1  警告: 0  持續時間 1 query: 0.000 sec. */

非索引列查詢
select count(*) from bdm_range_datetime1 where user_name='3999' and hiredate='2019-12-31';
/* Affected rows: 0  已找到記錄: 1  警告: 0  持續時間 1 query: 0.969 sec. */

跨兩分區非索引列查詢
select count(*) from bdm_range_datetime1 
where user_name='39998902' and (hiredate='2019-12-31' or hiredate='2020-01-01')
;
/* Affected rows: 0  已找到記錄: 1  警告: 0  持續時間 1 query: 1.859 sec. */


1個分區執行時間-hiredate索引
select count(*) from bdm_range_datetime where hiredate='2019-12-31';
/* Affected rows: 0  已找到記錄: 1  警告: 0  持續時間 1 query: 1.453 sec. */
id無索引 hiredate索引: 給分片鍵創建了索引,速度會更慢。
select count(*) from bdm_range_datetime where hiredate='2019-12-31' and id=3;
/* Affected rows: 0  已找到記錄: 1  警告: 0  持續時間 1 query: 37.703 sec. */


id無索引 hiredate沒有索引
select count(*) from bdm_range_datetime where hiredate='2019-12-31' and id=3;
/* Affected rows: 0  已找到記錄: 1  警告: 0  持續時間 1 query: 3.000 sec. */

1個分區執行時間-hiredate沒有索引
select count(*) from bdm_range_datetime where hiredate='2019-12-31';
/* Affected rows: 0  已找到記錄: 1  警告: 0  持續時間 1 query: 2.968 sec. */
2個分區執行時間
select count(*) from bdm_range_datetime where hiredate='2019-12-31' or hiredate='2020-01-02' ;
/* Affected rows: 0  已找到記錄: 1  警告: 0  持續時間 1 query: 1.516 sec. */

跨分區數量 執行時間(S)
1 0.7
2 1.5
3 2.7
4 3.8
5 5.0
6 6.4
7 7.8
8 9.5
9 11.3
10 13.2
11 15
12 17.3
13 19
14 21.6

統計結論增加一個分區不多1倍的執行時間。

14 分片鍵查詢

帶分片鍵
select * from bdm_range_datetime where hiredate='2021-01-04' and user_name='56003838'
/* Affected rows: 0 已找到記錄: 1 警告: 0 持續時間 1 query: 1.218 sec. */

跨7個分區
select * from bdm_range_datetime where (hiredate<'2021-01-08' and hiredate>'2020-08-04') and user_name='56003838';
/* Affected rows: 0 已找到記錄: 1 警告: 0 持續時間 1 query: 9.578 sec. */

不待分片鍵
select * from bdm_range_datetime where user_name='56003838';
/* Affected rows: 0 已找到記錄: 1 警告: 0 持續時間 1 query: 26.500 sec. */

差26倍。

總結

根據官網對分片鍵的限制解釋,經過測試,確實是這樣:

  • 如果一個表有主鍵了,分片鍵必須與主鍵組合主鍵。或刪除表的主鍵,單獨創建分片鍵進行分區。
  • 為分區鍵創建索引,執行效率會更慢。
  • 不管多少個分區,跨一個分區就會多一倍的執行時間
  • 條件包括分區鍵和非索引列 400W一個分區,執行時間為1秒,多一個分區就多1秒。
  • 條件包括分區鍵和索引列 400W一個分區,執行時間為0秒,多少分區沒有影響。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM