当前情况:大表的数据量已接近2亿条
我的解决思路:为它创建n*100个分区表,将各个分区表放在不同的tablespace上
这样做的优点:
1、首先是对这个级别的数据表的性能会有所提升
2、数据管理更科学
3、生产运维过程故障排查便捷
实验环境
VM Ware ESXi
Redhat 6.3 64bit
PostgreSQL 9.2/9.3
内存:2G
实现方法(同样适用于Oracle)
1、创建测试表
1 /** 2 创建300个分区表,每张表写入5万数据 3 */ 4 -- -------------------- step1 : CREATE TABLE-------------------- 5 DROP TABLE parttest; 6 CREATE TABLE parttest (some_test TEXT,some_tstimestamptz TEXT,random_value INT4, p_condition DATE) 7 PARTITION BY RANGE(p_condition) 8 ( 9 PARTITION p_2013_09_02_and_early VALUES LESS THAN ('2013-09-03') 10 );
2、已时间为分区条件,创建300个分区表的过程
1 -- -------------------- step2 : CREATE PARTITION PROCEDUCE -------------------- 2 CREATE OR REPLACE PROCEDURE create_partition_withindex() AS 3 4 DECLARE 5 tblname varchar := 'parttest'; 6 tblname_prefix varchar := 'p_condition'; 7 part_tbl_name varchar; 8 current_part_name varchar; 9 sql_addpartition_cmd varchar; 10 11 BEGIN 12 -- POPULATE SQL COMMAND 13 -- PARTITION TABLE'S NAME IS LIKE "TABLENAME_p_2019_12_31" 14 FOR j IN 1..300 LOOP 15 current_part_name := to_char(current_date + j,'YYYY_MM_DD'); 16 part_tbl_name := tblname_prefix || '_p_' || current_part_name; 17 18 -- POPULATE SQL COMMAND STRING 19 sql_addpartition_cmd = 'ALTER TABLE ' || tblname || ' ADD PARTITION p_' || current_part_name || ' VALUES LESS THAN (''' || (current_date + j + 1) || ''');'; 20 DBMS_OUTPUT.PUT_LINE(sql_addpartition_cmd); 21 EXECUTE IMMEDIATE sql_addpartition_cmd; 22 23 IF ((j % 30) = 0) THEN 24 COMMIT; 25 END IF; 26 27 END LOOP; 28 29 EXECUTE IMMEDIATE 'ALTER TABLE ' || tblname || ' ADD PARTITION p_' || to_char(current_date + 300 + 1,'YYYY_MM_DD') || '_and_later VALUES LESS THAN (''' || (current_date + 300 + 2) || ''');'; 30 END;
3、创建分区表
-- -------------------- step3 CREATE PARTITION -------------------- EXEC create_partition_withindex;
DEMO测试
1、创建写入数据的存储过程
1 -- -------------------- step4 CREATE TEST DATA PROCEDUCE -------------------- 2 3 CREATE OR REPLACE PROCEDURE create_partition_testdata() AS 4 5 DECLARE 6 7 BEGIN 8 FOR i IN 0..300 LOOP 9 INSERT INTO parttest (some_test, some_tstimestamptz, random_value,p_condition) 10 SELECT 11 'user #' || cast(floor(random() * 10) as int4), 12 now() - '1 year'::INTERVAL * random(), 13 cast(random() * 100000000 as INT4), 14 (current_date + i) 15 FROM 16 generate_series(1,500000); 17 COMMIT; 18 END LOOP; 19 END;
2、执行写入数据的存储过程
-- -------------------- step5 CREATE TEST DATA -------------------- EXEC create_partition_testdata;
3、检查写入数据的数据量
SELECT COUNT(*) FROM parttest;
如果有必要,在写入数据时可以记录一下创建分区表及写入数据的时间数据。