随机化大型MySQL表中的timestamp列

时间:2013-07-31 14:18:18

标签: mysql performance large-data

我有一个大约100米行的测试数据库表,它是通过多次克隆原始3k行生成的。假设此表描述了一些具有时间戳的事件。由于克隆现在我们每天有大约10万个事件,这远非真实案例。所以我想将日期列随机化并将记录分散几天。 这是我提出的程序:

DROP PROCEDURE IF EXISTS `randomizedates`;
DELIMITER //
CREATE PROCEDURE `randomizedates`(IN `daterange` INT)
BEGIN
  DECLARE id INT UNSIGNED;
  DECLARE buf TIMESTAMP;
  DECLARE done INT DEFAULT FALSE;
  DECLARE cur1 CURSOR FOR SELECT event_id FROM events;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  the_loop: LOOP
    FETCH cur1 INTO id;
    IF done THEN
      LEAVE the_loop;
    END IF;
    SET buf = (SELECT NOW() - INTERVAL FLOOR(RAND() * daterange) DAY);
    UPDATE events SET starttime = buf WHERE event_id = id;
  END LOOP the_loop;
  CLOSE cur1;
END //
DELIMITER ;

在3k表上,它执行约6秒,因此假设线性复杂,在100米的桌子上应用约50小时。有没有办法加快速度?或者我的程序可能不正确?

1 个答案:

答案 0 :(得分:1)

只是做:

set @datarange = 7;
update `events`
set starttime = NOW() - INTERVAL FLOOR(RAND()) * @datarange DAY;

数据库不擅长在lopp中获取和处理单行,就像我们习惯于在过程语言(迭代器,每个循环,数组等)中一样,它们是最好的,并且针对处理SQL进行了优化,这是本质上是一种声明性语言 - 与过程语言相比,你声明了你想要得到的东西,而不是指明如何去做。程序语言用来指定程序必须执行的步骤。

记住 - 一行一行=慢一点慢。

查看模拟表的简单示例,并将您的过程与UPDATE进行比较:

drop table `events`;
create table `events` as 
select * from information_schema.tables
where 1=0; 

alter table `events` add column event_id int primary key auto_increment first;

alter table `events` change column create_time starttime timestamp;

insert into `events`
select null, t.*
from information_schema.tables t
cross join (
  select 1 from information_schema.tables
  limit 100
) xx

mysql> select count(*) from `events`;
+----------+
| count(*) |
+----------+
|    17200 |
+----------+

我们创建了一个包含17,000行的表。现在我们称之为程序:

mysql> call `randomizedates`(7);
Query OK, 0 rows affected (34.26 sec)

和更新命令:

mysql>     set @datarange = 7;
Query OK, 0 rows affected (0.00 sec)

mysql>     update `events`
    ->     set starttime = NOW() - INTERVAL FLOOR(RAND()) * @datarange DAY;
Query OK, 17200 rows affected (0.23 sec)
Rows matched: 17200  Changed: 17200  Warnings: 0

如你所见 - 34秒/ 0.23秒= 14782%更快 - 这是一个巨大的差异!!!