mysql函数
创建分区表
动态地给分区时间
分区一般按时间分区,这里就以时间分区为例:
库名:liwinal_dev
表名:liwinal_temp
USE liwinal_dev;
-- 计算日期值
SET @date_3_days_ago = CONVERT(CURDATE() - INTERVAL 3 DAY USING utf8);
SET @date_2_days_ago = CONVERT(CURDATE() - INTERVAL 2 DAY USING utf8);
SET @date_1_day_ago = CONVERT(CURDATE() - INTERVAL 1 DAY USING utf8);
SET @date_today = CONVERT(CURDATE() USING utf8);
-- 创建表
SET @sql = CONCAT(
'CREATE TABLE `liwinal_temp` (',
'`mt_id` varchar(128) NOT NULL COMMENT ''id'',',
'`mt_open_id` varchar(100) DEFAULT NULL COMMENT ''openid'',',
'`mt_prize_id` varchar(128) DEFAULT NULL COMMENT ''奖ID'',',
'`create_time` datetime NOT NULL COMMENT ''创建时间'',',
'`update_time` datetime DEFAULT NULL COMMENT ''修改时间'',',
'PRIMARY KEY (`mt_id`, `create_time`)',
') ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT=''临时表''',
'PARTITION BY RANGE (TO_DAYS(create_time)) (',
'PARTITION p0 VALUES LESS THAN (TO_DAYS(''', @date_3_days_ago, ''')),',
'PARTITION p1 VALUES LESS THAN (TO_DAYS(''', @date_2_days_ago, ''')),',
'PARTITION p2 VALUES LESS THAN (TO_DAYS(''', @date_1_day_ago, ''')),',
'PARTITION p3 VALUES LESS THAN (TO_DAYS(''', @date_today, '''))',
')'
);
-- 先删除表(如果有)
SET @drop_sql = 'DROP TABLE IF EXISTS `liwinal_temp`';
PREPARE stmt FROM @drop_sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 创建新表
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
事件是否开启
-- 查看事件调度器状态
SHOW VARIABLES LIKE 'event_scheduler';
-- 开启事件调度器
SET GLOBAL event_scheduler = ON;
-- 关闭事件调度器
SET GLOBAL event_scheduler = OFF;
用事件定时更新分区
新增新的分区p4,删除旧分区p0数据,然后重新排序
USE liwinal_dev;
DELIMITER //
-- 删除事件
DROP EVENT IF EXISTS update_partitions;
-- 创建事件
CREATE EVENT IF NOT EXISTS update_partitions
ON SCHEDULE EVERY 1 DAY
STARTS TIMESTAMP(CURDATE() + INTERVAL 1 DAY, '02:00:00')
DO
BEGIN
-- 定义变量,需要放在开始事务之前,因为MySQL 的事务管理机制要求在事务开始之前,所有的变量定义都已经完成,事务开始后,你不能定义新的用户变量。
SET @date_1_day_ago = CURDATE() + INTERVAL 1 DAY;
-- 开始事务
START TRANSACTION;
ALTER TABLE `liwinal_temp` DROP PARTITION p0;
-- 动态生成 SQL 语句
SET @sql = CONCAT(
'ALTER TABLE `liwinal_temp` ADD PARTITION (',
'PARTITION p4 VALUES LESS THAN (TO_DAYS(''', @date_1_day_ago, '''))',
');'
);
-- 执行动态 SQL
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 查询分区 p1 的 VALUES LESS THAN 时间
SELECT PARTITION_DESCRIPTION INTO @p1_less_than
FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_NAME = 'liwinal_temp'
AND TABLE_SCHEMA = DATABASE()
AND PARTITION_NAME = 'p1';
-- 查询分区 p2 的 VALUES LESS THAN 时间
SELECT PARTITION_DESCRIPTION INTO @p2_less_than
FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_NAME = 'liwinal_temp'
AND TABLE_SCHEMA = DATABASE()
AND PARTITION_NAME = 'p2';
-- 查询分区 p3 的 VALUES LESS THAN 时间
SELECT PARTITION_DESCRIPTION INTO @p3_less_than
FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_NAME = 'liwinal_temp'
AND TABLE_SCHEMA = DATABASE()
AND PARTITION_NAME = 'p3';
-- 动态生成重新编号分区的 SQL 语句
SET @sql_reorganize_p1 = CONCAT(
'ALTER TABLE `liwinal_temp` REORGANIZE PARTITION p1 INTO (',
'PARTITION p0 VALUES LESS THAN (', @p1_less_than, ')',
');'
);
SET @sql_reorganize_p2 = CONCAT(
'ALTER TABLE `liwinal_temp` REORGANIZE PARTITION p2 INTO (',
'PARTITION p1 VALUES LESS THAN (', @p2_less_than, ')',
');'
);
SET @sql_reorganize_p3 = CONCAT(
'ALTER TABLE `liwinal_temp` REORGANIZE PARTITION p3 INTO (',
'PARTITION p2 VALUES LESS THAN (', @p3_less_than, ')',
');'
);
SET @sql_reorganize_p4 = CONCAT(
'ALTER TABLE `liwinal_temp` REORGANIZE PARTITION p4 INTO (',
'PARTITION p3 VALUES LESS THAN (TO_DAYS(''', @date_1_day_ago, '''))',
');'
);
-- 执行动态 SQL 重新编号分区
PREPARE stmt FROM @sql_reorganize_p1;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
PREPARE stmt FROM @sql_reorganize_p2;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
PREPARE stmt FROM @sql_reorganize_p3;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
PREPARE stmt FROM @sql_reorganize_p4;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 提交事务
COMMIT;
END //
DELIMITER ;
查询分区
SELECT
TABLE_NAME,
PARTITION_NAME,
PARTITION_ORDINAL_POSITION,
PARTITION_METHOD,
PARTITION_EXPRESSION,
PARTITION_DESCRIPTION,
TABLE_SCHEMA
FROM
INFORMATION_SCHEMA.PARTITIONS
WHERE
TABLE_NAME = 'liwinal_temp'
AND TABLE_SCHEMA = 'liwinal_dev';
只查某个分区的数据
-
使用 PARTITION 关键字
SELECT * FROM liwinal_temp PARTITION (p2); -
使用 EXPLAIN PARTITIONS
在执行查询之前,可以使用 EXPLAIN PARTITIONS 来查看 MySQL 是否会自动选择特定的分区。这有助于优化查询,确保 MySQL 只扫描相关的分区。
EXPLAIN PARTITIONS SELECT * FROM liwinal_temp WHERE create_time >= '2025-08-03' AND create_time < '2025-08-04'; -
优化查询条件
确保查询条件能够匹配分区的范围,这样 MySQL 可以自动选择相关的分区。例如,如果你的分区是按日期范围划分的,查询条件应该包含日期范围。
SELECT * FROM liwinal_temp WHERE create_time >= '2025-08-03' AND create_time < '2025-08-04';
查看事务
USE liwinal_dev;
SHOW EVENTS;
过程函数
-
有一些需要动态创建的sql可以利用过程函数完成
-
可以重复执行的sql也可以用过程函数
语法
删除表的过程函数
DROP PROCEDURE IF EXISTS 过程函数名;
创建表的过程函数
注意过程函数名后要加括号
DELIMITER //
CREATE PROCEDURE 过程函数名()
BEGIN
过程函数要执行的sql
END //
DELIMITER ;
使用过程函数
注意过程函数名后要加括号
CALL 过程函数名();
利用过程函数批量新增数据
少量数据
USE liwinal_dev
-- 删除表的过程函数
DROP PROCEDURE IF EXISTS GenerateData;
-- 创建表的过程函数
DELIMITER //
CREATE PROCEDURE GenerateData()
BEGIN
DECLARE i INT DEFAULT 1;
WHILE i <= 100 DO
INSERT INTO `liwinal_temp`
(`lt_id`, `lt_open_id`, `lt_prize_id`, `create_time`, `update_time`)
VALUES (
CONCAT('User', i),
CONCAT('oMnE95GXA', i),
'jp1000000206',
'2025-08-01 15:12:23',
'2025-08-01 15:12:23'
);
SET i = i + 1;
END WHILE;
END //
DELIMITER ;
-- 执行表的过程函数
CALL GenerateData();
大量数据
USE liwinal_dev;
-- 删除表的过程函数
DROP PROCEDURE IF EXISTS GenerateData;
-- 创建表的过程函数
DELIMITER //
CREATE PROCEDURE GenerateData()
BEGIN
DECLARE i INT DEFAULT 1;
DECLARE batch_size INT DEFAULT 100; -- 每次插入 100 条数据
DECLARE values_list TEXT DEFAULT '';
WHILE i <= 400000 DO
-- 这里双引号和\'任选一个编写都行
SET values_list = CONCAT(values_list, '("F', i, '", \'oMnE95GXA\', \'jp1000000206\', \'2025-08-03 11:12:23\', \'2025-08-03 11:12:23\'),');
SET i = i + 1;
-- 每当积累到 batch_size 条数据时,执行一次批量插入
IF i % batch_size = 0 OR i > 400000 THEN
SET values_list = SUBSTRING(values_list, 1, LENGTH(values_list) - 1); -- 去掉最后一个逗号
SET @sql = CONCAT('INSERT INTO liwinal_temp (lt_id, lt_open_id, lt_prize_id, create_time, update_time) VALUES ', values_list);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET values_list = ''; -- 重置 values_list
END IF;
END WHILE;
END //
DELIMITER ;
-- 执行表的过程函数
CALL GenerateData();

浙公网安备 33010602011771号