将Mysql中的2000万个数据划分为批.请建议一个更快的方法



我有一个数据库表user_data,总行数为2000万。它基本上是用户的地址数据。一个用户可以有多个地址。user_id采用字符串格式。

我需要将2000万个数据划分为10个批次,并针对每一行更新相应的batch_no。具有相同User_id的用户应该在同一批中。

为此,我使用php脚本和更新联接查询(用于联接的字段的格式为varchar(。现在,更新2000万行大约需要60-70分钟。user_id列的类型为varchar(255(,并进行了索引。

任何有助于加快这一进程的帮助都将不胜感激。

$query = "SELECT COUNT(DISTINCT user_id) from user_data WHERE set=1";
$stmt = $this->db->prepare($query);
$stmt->execute([':set'=> $this->set]);
$totalUserCount = $stmt->fetchColumn();
$limit = intval($totalUserCount/10);
$lastRecords = $totalUserCount%10;
$limit = $lastRecords > 0 ? $limit + 1 : $limit;
$lastOffset = false;
for($i = 0 ; $i < 10 ; $i++)
{
$offset =  $limit * $i;
if($lastOffset)
$offset = ($limit * $i) + $lastRecords;

$query = "UPDATE user_data t1 INNER JOIN (SELECT distinct user_id FROM user_data 
WHERE set=1 LIMIT :offset, :limit) AS t2 
ON (t1.user_id = t2.user_id AND t1.set =1) 
SET batch_no=:batch_no";
$stmt = $this->db->prepare($query);
$batchNo = ($i+1);
$stmt->bindParam(':batch_no',$batchNo,PDO::PARAM_INT);
$stmt->bindParam(':set',1,PDO::PARAM_STR);
$stmt->bindParam(':offset',$offset,PDO::PARAM_INT);
$stmt->bindParam(':limit',$limit,PDO::PARAM_INT);
$stmt->execute();
if($lastRecords==($i+1)){
$limit--; 
$lastOffset = true;                    
}
}

表格结构和样本数据

--
-- Table structure for table `user_data`
--
CREATE TABLE `user_data` (
`id` int(11) NOT NULL,
`user_id` varchar(255) NOT NULL,
`address_1` varchar(255) NOT NULL,
`address_2` varchar(255) NOT NULL,
`set_no` int(11) NOT NULL,
`batch_no` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
--
-- Indexes for dumped tables
--
--
-- Indexes for table `user_data`
--
ALTER TABLE `user_data`
ADD PRIMARY KEY (`id`),
ADD KEY `idx_user_id` (`user_id`);
--
-- AUTO_INCREMENT for dumped tables
--
--
-- AUTO_INCREMENT for table `user_data`
--
ALTER TABLE `user_data`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
COMMIT;
道12<1>>td style="text-align:left;">3td style="text-align:left;">4>GDJFDHFH004大街>DF-01>td style="ext-align:center;">中央阿拉巴马州/table>
id>
1ABCDEFGH001北大街2ABCDEFGH001ABCDEFGH00113号车道5HHSYEEEY002阿拉巴马州
6HHSYEEEY002GH-15
7TETYJEE056AKSH-56

这确实是评论,但篇幅有限。

您谈论的是数据库性能,但没有提供表/索引结构的详细信息,也没有解释计划。

我需要将2000万个数据划分为10个批次,并根据每行更新相应的batch_no

这听起来像是你只会做一次的事情——那么为什么要让它更快呢?

你为什么要把数据分成10批?这些批次的用途是什么?

在您的代码中,我看不到为$batchno分配值的任何地方

这看起来像XY问题。

假设user_data.migration_batch是一个标称值,user_id被实现为一个整数序列而不重复间隙,那么只需运行就可以更快地获得相同的结果(但结果本身的值非常可疑(

UPDATE user_data 
SET migration_batch=MOD(user_id, 10);

(但请注意,这并不能解决当您实际开始对任何东西使用批号时会出现的性能问题(。

给定创建的betweed user_id和migration_batch的简单函数映射。。。。。您甚至需要麻烦在数据库中存储migrationbatch吗?