如何检查/更新数据库中的列包含大约百万行?

时间:2018-04-08 16:47:31

标签: php mysql sql performance pdo

我有MYSQL数据库,其中包含大约一百万(1,000,000)行,我想检查所有行并根据条件更新一些,所以例如我运行这样的SQL语句:

select messageid from messages where messageid !=""

然后我获取所有ID并将它们存储在变量中:

$existMessages;

然后我生成一个4个字符的字符串0-9a-z:

function generateRandomString($length = 4) {
    return substr(str_shuffle(str_repeat($y='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', ceil($length/strlen($y)) )),1,$length);
}

然后我用生成的字符串更新现有ID,检查生成的ID是否唯一。

随着行的增加,此过程变慢并占用整个CPU。

有没有更好的方法呢?就像在MYSQL中直接使用SQL语句一样?或者该怎么办?

4 个答案:

答案 0 :(得分:0)

您应首先在要唯一的列上添加unique or primary约束。

之后,您可以执行更新命令

UPDATE TABLE_NAME SET COLMUN_NAME=generateRandomString() WHERE messageid !="";

答案 1 :(得分:0)

您可以直接使用SQL,并根据行中的某些数据创建一个简单的哈希,例如:

UPDATE table_name SET messageid = MD5(messageid) WHERE messageid !="";

您可能希望批量执行此操作,因此请在语句中添加LIMIT,即。限制0,1000一次做一堆。

答案 2 :(得分:0)

您可以使用以下更新条款。这将为大写和0-9选择4个随机字母和数字。

update table_name cross join (select 
@chars:='1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIKLMNOPQRSTUVWXYZ') tab
set messageid = concat(substring(@chars, floor(rand()*61) + 1, 1),
               substring(@chars, floor(rand()*61) + 1, 1),
               substring(@chars, floor(rand()*61) + 1, 1),
              substring(@chars, floor(rand()*61) + 1, 1)
          )
where messageid !="";

答案 3 :(得分:0)

我不再需要检查'并使其更快。

这样的4个字符的字符串不会超过一百万个。因此,如果您随机选择重复数据,则会出现烦人的重复数量。生成它们。

相反,我建议

  1. 生成所有这些(或一百万个)
  2. 随机播放
  3. 将它们应用到您的桌子上。

    • CONV(x, 10, 36)将从x生成base-36(0-9A-Z)值。但是,以下可能会更好......
    • 构建一个包含36行0..9,a..z。
    • 的表
    • CROSS JOIN它自己4次生成所有36 ^ 4个组合。
    • ORDER BY RAND()会在没有导致重复的情况下将其洗牌。
    • 多表UPDATE可让您将4-char字符串从一个表复制到另一个表。