MySQL和ORACLE每天自动增加分区

本文介绍了一种针对大量数据的MySQL表进行自动分区的方法,通过创建存储过程和定时事件实现每天自动增加新的分区,并提供了具体实现步骤及SQL示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有一个表tb_3a_huandan_detail,每天有300W左右的数据。查询太慢了,网上了解了一下,可以做表分区。由于数据较大,所以决定做定时任务每天执行存过自动进行分区。

1、在进行自动增加分区前一定得先对表手动分几个区

复制代码
1 ALTER TABLE tb_3a_huandan_detail PARTITION BY RANGE (TO_DAYS(ServiceStartTime))
2 (
3     PARTITION p20160523 VALUES LESS THAN (TO_DAYS('2016-05-23')),
4     PARTITION p20160524 VALUES LESS THAN (TO_DAYS('2016-05-24')),
5     PARTITION p20160525 VALUES LESS THAN (TO_DAYS('2016-05-25')),
6     PARTITION p20160526 VALUES LESS THAN (TO_DAYS('2016-05-26')),
7     PARTITION p20160527 VALUES LESS THAN (TO_DAYS('2016-05-27'))
8 )
复制代码

2、分区存过如下:

复制代码
 1 DELIMITER $$
 2 
 3 USE `nres`$$
 4 
 5 DROP PROCEDURE IF EXISTS `create_Partition_3Ahuadan`$$
 6 
 7 CREATE DEFINER=`nres`@`%` PROCEDURE `create_Partition_3Ahuadan`()
 8 BEGIN
 9 /* 事务回滚,其实放这里没什么作用,ALTER TABLE是隐式提交,回滚不了的。*/
10     DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK;
11     START TRANSACTION;
12  
13 /* 到系统表查出这个表的最大分区,得到最大分区的日期。在创建分区的时候,名称就以日期格式存放,方便后面维护 */
14     SELECT REPLACE(partition_name,'p','') INTO @P12_Name FROM INFORMATION_SCHEMA.PARTITIONS 
15     WHERE table_name='tb_3a_huandan_detail' ORDER BY partition_ordinal_position DESC LIMIT 1;
16      SET @Max_date= DATE(DATE_ADD(@P12_Name+0, INTERVAL 1 DAY))+0;
17 /* 修改表,在最大分区的后面增加一个分区,时间范围加1天 */
18     SET @s1=CONCAT('ALTER TABLE tb_3a_huandan_detail ADD PARTITION (PARTITION p',@Max_date,' VALUES LESS THAN (TO_DAYS (''',DATE(@Max_date),''')))');
19     /* 输出查看增加分区语句*/
20     SELECT @s1;
21     PREPARE stmt2 FROM @s1;
22     EXECUTE stmt2;
23     DEALLOCATE PREPARE stmt2;
24 /* 取出最小的分区的名称,并删除掉 。
25     注意:删除分区会同时删除分区内的数据,慎重 */
26     /*select partition_name into @P0_Name from INFORMATION_SCHEMA.PARTITIONS 
27     where table_name='tb_3a_huandan_detail' order by partition_ordinal_position limit 1;
28     SET @s=concat('ALTER TABLE tb_3a_huandan_detail DROP PARTITION ',@P0_Name);
29     PREPARE stmt1 FROM @s; 
30     EXECUTE stmt1; 
31     DEALLOCATE PREPARE stmt1; */
32 /* 提交 */
33     COMMIT ;
34  END$$
35 
36 DELIMITER ;

3、增加定时事件

复制代码
 1 DELIMITER ||  
 2 CREATE EVENT Partition_3Ahuadan_event  
 3           ON SCHEDULE  
 4           EVERY 1 day STARTS '2016-05-27 23:59:59'   
 5           DO  
 6       BEGIN  
 7 
 8           CALL nres.`create_Partition_3Ahuadan`;  
 9         
10  END ||  
11 DELIMITER ;  


===================================================================================================
按照上面的过程,自己写的一个每日自动分区SP,过程如下:

(1)创建分区表:


(2)自动分区存储过程:

(3)创建定时事件
 DELIMITER ||  
 CREATE EVENT Partition_auto_add_event  
            ON SCHEDULE  
            EVERY 1 day STARTS '2017-02-19 23:59:59'   
            DO  
        BEGIN  
  
            CALL test.`create_partition_auto_add`;  
          
  END ||  
 DELIMITER ; 

====================================================================================================
查看分区表的SQL:可以直接用 select * from table_name partition p1;

下面是介绍一下ORACLE 11g 的interval 自动创建子分区
在11g里的Interval创建,这种方法对没有写全的分区会自动创建。 比如我这里只写了1月日期,如果插入的数据有其他月份的,会自动生成对应的分区。

 

/* Formatted on 2011/03/02 15:41:09 (QP5 v5.115.810.9015) */

CREATE TABLE intervaldave

PARTITION BY RANGE (time_fee)

   INTERVAL ( NUMTOYMINTERVAL (1, 'MONTH') )

   (PARTITION part1

       VALUES LESS THAN (TO_DATE ('01/12/2010', 'MM/DD/YYYY')))

AS

   SELECT   ID, TIME_FEE FROM DAVE;

 

 

SQL> select table_name,partition_name from user_tab_partitions where table_name='INTERVALDAVE';

 

TABLE_NAME                     PARTITION_NAME

------------------------------ ------------------------------

INTERVALDAVE                   PART1

INTERVALDAVE                   SYS_P24

INTERVALDAVE                   SYS_P25

INTERVALDAVE                   SYS_P26

INTERVALDAVE                   SYS_P33

INTERVALDAVE                   SYS_P27

INTERVALDAVE                   SYS_P28


下面再补充一下两个函数:

numtodsinterval(<x>,<c>),x是一个数字,c是一个字符串,

表明x的单位,这个函数把x转为interval day to second数据类型
常用的单位有 ('day','hour','minute','second')
example
SQL> select sysdate,sysdate+numtodsinterval(3,'hour') as res from dual;
SYSDATE             RES
------------------- -------------------
2007-09-05 01:45:34 2007-09-05 04:45:34
numtoyminterval与numtodsinterval函数类似,将x转为interval year to month数据类型
常用的单位有'year','month'
example
SQL> select sysdate,sysdate+numtoyminterval(3,'year') as res from dual;
SYSDATE             RES
------------------- -------------------
2007-09-05 01:54:53 2010-09-05 01:54:53




<think>好的,用户现在想了解SQL Server、MySQLOracle分区表的差异,特别是实现方式区别。之前我已经回答了它们表空间的不同,现在需要聚焦在分区表上。首先,我得回忆一下这三个数据库的分区机制。 根据用户提供的引用[1],MySQL的MyISAM分区表使用的是通用分区策略,由server层控制,性能有问题。这可能指的是旧版本的情况,现在InnoDB是否有所改进呢?需要确认当前MySQL版本的分区实现是否有变化。另外,引用[3]提到了日期字段的处理差异,虽然主要是语法上的,但可能影响分区策略的设计。 用户之前的问题是关于表空间的区别,现在转向分区表,这两者有关联。比如Oracle分区表可以分配到不同表空间,而MySQL分区可能涉及独立表空间。需要区分分区表空间的概念,避免混淆。 接下来,我需要整理每个数据库的分区实现方式: 1. **Oracle**:应该支持范围、列表、哈希、复合分区,还有自动分区如间隔分区分区剪裁性能优化比较成熟,可能表空间结合使用,每个分区可以存储在不同表空间,方便管理IO分散。 2. **SQL Server**:使用文件组来分布分区,常见的是水平分区,通过分区函数方案。比如按日期范围分区,每个分区对应不同的文件组,可能利用列存储索引优化查询。 3. **MySQL**:虽然支持分区,但根据引用[1],MyISAM的分区由server层控制,性能不佳。InnoDB是否有改进?比如,是否支持更高效的分区策略?MySQL分区类型包括RANGE、LIST、HASH等,但实际应用中可能存在限制,比如所有分区必须同一存储引擎,无法跨磁盘等。 需要注意用户提供的引用中提到的问题,比如MySQL的通用分区策略性能问题,这可能影响使用场景。此外,用户可能关心性能差异、管理复杂度、适用场景等。 现在需要比较三者的实现差异,包括分区类型、管理方式、存储结构、性能优化手段等。同时,用户可能想知道实际应用中的选择建议,比如高并发OLTP适合哪个,大数据量分析适合哪个。 还要确保回答结构清晰,分点说明每个数据库的特点,然后对比差异,可能用表格总结,最后给出建议。需要引用用户提供的引用内容,比如引用[1]说明MySQL分区问题,引用[3]在日期处理上的不同可能影响分区定义。 需要确认是否有遗漏的重要区别,比如分区键的限制、索引处理、维护操作(如分区的添加、删除、合并)是否方便,以及是否支持并行查询等高级功能。 最后,生成相关问题,引导用户深入探讨,比如分区表的性能优化策略,或者具体某个数据库中分区的实际案例。</think>### SQL Server vs MySQL vs Oracle 分区表实现与差异对比 --- #### 一、核心实现机制 1. **Oracle 分区表** - **实现基础**:基于表空间物理隔离,每个分区可分配到不同表空间,结合 *分区键* 实现数据逻辑划分[^1] - **分区策略**: - **范围分区**:按连续值划分(如日期范围 `PARTITION BY RANGE(order_date)`) - **列表分区**:按枚举值划分(如地区 `PARTITION BY LIST(region)`) - **哈希分区**:均匀分布数据(`PARTITION BY HASH(customer_id)`) - **复合分区**:多级组合(如先范围再哈希) - **高级特性**: - **间隔分区**:自动创建新分区(如按月自动扩展) - **分区剪裁**:查询时自动跳过无关分区 - **分区交换**:快速加载/卸载数据(`ALTER TABLE ... EXCHANGE PARTITION`) 2. **MySQL 分区表** - **实现基础**:依赖存储引擎(InnoDB/MyISAM),但分区逻辑由 *Server层统一管理*,与引擎解耦[^1] - **分区策略**: - **RANGE/LIST**:语法与Oracle类似(`PARTITION BY RANGE(YEAR(order_date))`) - **HASH/KEY**:基于哈希函数或系统计算的分区 - **限制**: - 所有分区必须使用同一存储引擎 - 不支持全局索引(仅本地索引) - 分区键必须包含所有唯一约束字段(如主键) - **性能问题**: - 通用分区策略(Generic Partitioning)导致高频访问时性能下降,尤其是MyISAM引擎[^1] 3. **SQL Server 分区表** - **实现基础**:通过 *分区函数* *分区方案* 映射到文件组,物理隔离依赖文件组[^2] - **核心流程**: 1. 创建分区函数定义边界(`CREATE PARTITION FUNCTION`) 2. 创建分区方案绑定文件组(`CREATE PARTITION SCHEME`) 3. 建表时指定分区方案 - **典型策略**: - **水平分区**:按范围拆分(如按年份划分订单表) - **列存储索引分区**:优化OLAP查询性能 --- #### 二、关键差异对比(表格形式) | **维度** | **Oracle** | **MySQL** | **SQL Server** | |-----------------------|-------------------------------------|------------------------------------|------------------------------------| | **物理存储** | 分区可独立分配表空间 | 所有分区在同一存储引擎文件中 | 分区映射到不同文件组 | | **索引支持** | 全局索引+本地索引 | 仅本地索引 | 支持分区对齐的聚集/非聚集索引 | | **自动化能力** | 间隔分区自动创建新分区) | 需手动维护分区 | 需手动或通过作业维护分区 | | **性能优化** | 分区剪裁、并行查询 | 分区过滤依赖查询优化器 | 列存储索引加速分析查询 | | **典型限制** | 分区键需显式定义 | 主键必须包含分区键 | 分区函数仅支持单列 | --- #### 三、操作示例对比 1. **创建范围分区表** - **Oracle**(按日期分区): ```sql CREATE TABLE sales ( sale_id NUMBER, sale_date DATE ) PARTITION BY RANGE(sale_date) ( PARTITION p2023 VALUES LESS THAN (TO_DATE('2024-01-01', 'YYYY-MM-DD')), PARTITION p2024 VALUES LESS THAN (MAXVALUE) ); ``` - **MySQL**(按年份分区): ```sql CREATE TABLE sales ( sale_id INT PRIMARY KEY, sale_date DATE ) PARTITION BY RANGE(YEAR(sale_date)) ( PARTITION p2023 VALUES LESS THAN (2024), PARTITION p2024 VALUES LESS THAN MAXVALUE ); ``` - **SQL Server**(绑定文件组): ```sql CREATE PARTITION FUNCTION pf_sales (INT) AS RANGE RIGHT FOR VALUES (2024); CREATE PARTITION SCHEME ps_sales AS PARTITION pf_sales TO (fg2023, fg2024); CREATE TABLE sales ( sale_id INT, sale_year INT ) ON ps_sales(sale_year); ``` 2. **动态管理分区** - **Oracle 添加分区**: ```sql ALTER TABLE sales ADD PARTITION p2025 VALUES LESS THAN (TO_DATE('2026-01-01', 'YYYY-MM-DD')); ``` - **MySQL 重组分区**: ```sql ALTER TABLE sales REORGANIZE PARTITION p2024 INTO ( PARTITION p2024 VALUES LESS THAN (2025), PARTITION p2025 VALUES LESS THAN MAXVALUE ); ``` - **SQL Server 滑动窗口**: ```sql -- 归档旧数据并添加新分区 ALTER PARTITION SCHEME ps_sales NEXT USED [PRIMARY]; ALTER PARTITION FUNCTION pf_sales() SPLIT RANGE (2025); ``` --- #### 四、设计影响与选型建议 1. **Oracle** - **适用场景**:高频写入的OLTP系统(如金融交易表按月分区) - **优势**:分区剪裁减少I/O、全局索引加速查询 2. **MySQL** - **适用场景**:中小规模数据(如日志表按周分区) - **注意事项**:避免高频写入分区表,谨慎选择分区键[^1] 3. **SQL Server** - **适用场景**:大规模数据分析(如按日期分区+列存储索引) - **优势**:文件组隔离冷热数据,优化存储成本 --- ### 总结 - **Oracle**:功能最完备,适合企业级复杂分区需求 - **MySQL**:轻量化但限制多,需避免性能瓶颈[^1] - **SQL Server**:强于分析场景,与Windows生态深度整合 --- ### 相关问题 1. 如何评估Oracle分区表是否启用了分区剪裁? 2. MySQL分区表在哪些场景下性能可能反而不如单表? 3. SQL Server如何利用分区实现数据归档自动化?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值