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

Posted

技术标签:

【中文标题】如何检查/更新数据库中包含大约百万行的列?【英文标题】:How to check/update columns in a database contains about million rows? 【发布时间】:2018-04-08 16:47:30 【问题描述】:

我有一个包含大约一百万 (1,000,000) 行的 mysql 数据库,我想检查所有行并根据条件更新一些行,例如我运行这样的 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语句?或者怎么办?

【问题讨论】:

你应该使用MySQL Store Procedure 也许这是一次性的事情,让他们都拥有它,并且无论在哪里插入这些都应该添加唯一 ID?那你就不必这样做了吗? @James,是的,一般情况下应该是一样的,但这是一个特殊情况,我需要不时用唯一的随机值更新此列 “不时”,但如果这是在 INSERT 代码中,您就不需要再这样做了吗?插入已经完成了 我不明白这个查询的目的select messageid from messages where messageid !=""你选择了id,当你知道id是什么时通过id?也许这只是一个例子,但它是一个糟糕的例子,因为有优化选择的方法,但我们需要真正的选择。例如,如果您有一个唯一字段并且想要插入数据,则捕获重复键错误比执行选择和插入更快,因为您不必运行 1 个查询。 【参考方案1】:

您应该首先在您想要唯一的列上放置一个unique or primary 约束。

之后就可以执行更新命令了

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

【讨论】:

【参考方案2】:

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

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

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

【讨论】:

"随着行数的增加,这个过程会变慢并占用整个 CPU。"当使用较大的偏移量时,具有 LIMIT 的 qeuries 也会变慢。【参考方案3】:

您可以使用以下更新子句。这将为小写和大写以及 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 !="";

【讨论】:

【参考方案4】:

我将消除对“检查”的需要,并使其更快。

这样的 4 字符字符串不超过一百万。因此,如果您“随机”生成它们,将会有大量令人讨厌的重复项。

相反,我推荐

    全部生成(或一百万个) 随机播放

    将它们应用到您的桌子上。

    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 字符字符串从一个表复制到另一个表。

【讨论】:

以上是关于如何检查/更新数据库中包含大约百万行的列?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SQL Server 中更新具有数百万行的大表?

如何在 qlik 意义上用另一种方式替换大数据(大约百万行)上的 for..loop

mysql中数百万行的基于键的分区

如何用qlik意义上的另一种方式替换大数据(大约数百万行)的for循环

在 SQL Server 2017 上创建具有 800+ 百万行的现有分区表的列存储索引

如何使用SQL更新VBA Access中包含NULL值的列?