我有一个非常大的(300M行)表,其中包含列:
date - datetime
uid - byte(16)
event_number - bigint
start_time - datetime
end_time - datetime
我目前在日期列上有一个索引,以及uid
和event_number
上的唯一索引。
我会定期收到结束时间的更新,因此请使用以下ETL查询:
INSERT INTO myTable (date, uid, event_number, start_time, end_time )
SELECT date, uid, event_number, start_time, end_time
FROM myStagingTable
ON DUPLICATE KEY UPDATE end_time = end_time;
我已经开始删除过时的数据,为此,我的大多数表都使用日期列上的范围分区进行分区,每月分区。
我想使用相同的基于范围的分区来设置上表。
但是,这与不属于分区功能的UNIQUE INDEX
列不兼容。因此,我尝试用date
,uid
和event_number
上的连接和简单索引替换上述查询,而不是使用唯一索引。
UPDATE MyTable t
INNER JOIN MyStagingTable s ON t.uid = s.uid
AND t.event_number = s.event_number AND t.`date` = s.`date`
SET t.end_time = s.end_time;
CREATE TEMPORARY TABLE tmpStaging AS
SELECT s.date, s.uid, s.event_number, s.start_time, s.end_time
FROM myStagingTable s
LEFT JOIN myTable t on t.uid = s.uid AND s.event_number = t.event_number;
WHERE t.uid IS NULL;
// then use above insert statement against tmpStaging without the ON DUPLICATE clasuse.
但是,对于大约200万行的一些测试数据,此更新过程大约是原始设置的15倍。我看不到更好的方法,但是真的想在这个表中引入分区。
我在AWS RDS上使用MySQL 5.7并且内存有限,但实际上没有使用交换内存。