我目前正在开发一个MySQL Db超过800万行的项目。我已经提供了一部分来测试它的一些查询。它有大约20列,其中5列对我有用。即:First_Name, Last_Name, Address_Line1, Address_Line2, Address_Line3, RefundID
我必须为每一行创建一个唯一但随机的RefundID
,这不是问题。问题是为那些RefundID
相同的行创建相同 First_Name, Last_Name, Address_Line1, Address_Line2, Address_Line3
。
这是我第一次与MySQL有大量行数相关的实际工作。到目前为止,我已经创建了这些查询:
-- Creating Teporary Table --
CREATE temporary table tempT (SELECT tt.First_Name, count(tt.Address_Line1) as
a1, count(tt.Address_Line2) as a2, count(tt.Address_Line3) as a3, tt.RefundID
FROM `tempTable` tt GROUP BY First_Name HAVING a1 >= 2 AND a2 >= 2 AND a3 >= 2);
-- Updating Rows with First_Name from tempT --
UPDATE `tempTable` SET RefundID = FLOOR(RAND()*POW(10,11))
WHERE First_Name IN (SELECT First_Name FROM tempT WHERE First_Name is not NULL);
此更新查询继续运行但永不结束,tempT
行超过30K。然后,此查询将在主DB上运行,行数超过800K。
有人可以帮我解决这个问题吗?
此致
答案 0 :(得分:1)
对我来说显而易见的解决方案......
不要使用随机值 - 使用哈希:
UPDATE yourtable
SET refundid = MD5('some static salt', First_Name
, Last_Name, Address_Line1, Address_Line2, Address_Line3)
问题在于,如果你使用整数值作为refundId,那么很有可能发生碰撞(暗示CONV(SUBSTR(MD5(...),1,16),16,10获得一个签名的BIGINT)。但是你没有说出这个领域的类型,也没有说出“独特”这个领域的严格程度。要求是。它确实在一次通过中执行更新。
创建密集数字序列的替代方法是创建一个临时表,其中包含原始表中的唯一值和随机值。按随机值排序并设置单调递增的refundId - 然后将其用作查找表或更新原始表:
SELECT DISTINCT First_Name
, Last_Name, Address_Line1, Address_Line2, Address_Line3
INTO temptable
FROM yourtable;
set @counter=-1;
UPDATE temptable t SET t,refundId=(@counter:=@counter + 1)
ORDER BY r.randomvalue;
还有其他解决方案 - 但效率更高的解决方案依赖于拥有多个数据副本和/或使用过程语言。
答案 1 :(得分:0)
尝试使用以下内容:
UPDATE `tempTable` x SET RefundID = FLOOR(RAND()*POW(10,11))
WHERE exists (SELECT 1 FROM tempT y WHERE First_Name is not NULL and x.First_Name=y.First_Name);
答案 2 :(得分:0)
在MySQL中,将join
与update
一起使用通常比使用子查询过滤where
子句更有效。以下可能表现更好:
UPDATE `tempTable` join
(SELECT distinct First_Name
FROM tempT
WHERE First_Name is not NULL
) fn
on temptable.First_Name = fn.First_Name
SET RefundID = FLOOR(RAND()*POW(10,11));