我有一个超过1600万行的MySQL表,没有主键。每当我尝试添加一个,我的连接崩溃。我尝试在PHPMyAdmin和shell中添加一个作为自动增量,但是大约10分钟后连接总是丢失。
我想要做的是在PHP中遍历表格的行,这样我就可以限制结果的数量,并且每个返回的行都会添加一个自动递增的ID号。由于通过减少MySQL查询的负载会减少受影响的行数,因此我不会失去连接。
我想做点什么
SELECT * FROM MYTABLE LIMIT 1000001, 2000000;
然后,在循环中,更新当前行
UPDATE (current row) SET ID='$i++'
我该怎么做?
注意:原始数据是作为txt文件提供给我的。我不知道是否有重复但我无法消除任何行。此外,不会添加任何行。此表仅用于查询目的。但是,当我添加索引时,没有问题。
答案 0 :(得分:1)
我怀疑你正在尝试使用phpmyadmin来添加索引。虽然它很方便,但它是一个PHP脚本,并且与服务器上的任何PHP脚本的资源相同,通常运行时间为30-60秒,并且RAM数量有限。
建议您获取添加索引所需的mysql查询,然后使用SSH进行shell,并使用命令行MySQL添加索引。
答案 1 :(得分:0)
如果您没有重复的行,那么以下方式可能会有所启发:
假设您要更新第一个 10000 行的自动递增值。
UPDATE
MYTABLE
INNER JOIN
(SELECT
*,
@rn := @rn + 1 AS row_number
FROM MYTABLE,(SELECT @rn := 0) var
ORDER BY SOME_OF_YOUR_FIELD
LIMIT 0,10000 ) t
ON t.field1 = MYTABLE.field1 AND t.field2 = MYTABLE.field2 AND .... t.fieldN = MYTABLE.fieldN
SET MYTABLE.ID = t.row_number;
对于下一个 10000 行,只需要更改两件事:
(SELECT @rn := 10000) var
LIMIT 10000,10000
重复..
注意: ORDER BY SOME_OF_YOUR_FIELD
非常重要,否则您会以随机顺序获得结果。最好创建一个可能需要限制的函数,作为参数偏移并完成这项工作。因为你需要重复这个过程。
<强>解释强>
我们的想法是创建一个临时表( t ),其行数为N
,并为每一行分配unique row number
。稍后在主表MYTABLE
和此临时表t
之间建立内部联接,以匹配所有字段,然后更新相应行的ID
字段(在MYTABLE
中)使用递增的值(在本例中为row_number
)。
另一个IDEA:
您可以使用multithreading in PHP
来完成这项工作。
N
个帖子。1 to 10000, 10001 to
20000 etc
),就像上面的查询一样。警告: 更高偏移量 中的查询将更慢。