带限制的MySQL批处理查询

带限制的MySQL批处理查询,mysql,sql,optimization,Mysql,Sql,Optimization,我需要更改MySQL表中几个财产的所有权。让我大吃一惊的是,有好几种相同的商品,我不想全部换掉 现在,我正在使用这样的查询: UPDATE possessions SET citizen_id=1 WHERE citizen_id=2 AND good_id=8 LIMIT 1 UPDATE possessions SET citizen_id=2 WHERE citizen_id=4 AND good_id=2 LIMIT 1 UPDATE possessions SET citizen_id

我需要更改MySQL表中几个财产的所有权。让我大吃一惊的是,有好几种相同的商品,我不想全部换掉

现在,我正在使用这样的查询:

UPDATE possessions SET citizen_id=1 WHERE citizen_id=2 AND good_id=8 LIMIT 1
UPDATE possessions SET citizen_id=2 WHERE citizen_id=4 AND good_id=2 LIMIT 1
UPDATE possessions SET citizen_id=4 WHERE citizen_id=3 AND good_id=5 LIMIT 2
UPDATE possessions AS p
INNER JOIN
(
  SELECT
    @r := @r * (@c = p.citizen_id AND @g = p.good_id) + 1 AS r,
    p.possession_id,
    @c := p.citizen_id AS citizen_id,
    @g := p.good_id AS good_id
  FROM
    possessions AS p
  CROSS JOIN
    (SELECT @r := 0, @c := 0, @g := 0) AS x
  ORDER BY
    p.citizen_id,
    p.good_id
) AS f ON p.possession_id = f.possession_id
INNER JOIN
  possession_updates AS u ON u.citizen_id = f.citizen_id AND u.good_id = f.good_id
SET
  p.citizen_id = u.new_citizen_id
WHERE
  f.r <= u.row_count
;
有时候,有很多这样的东西,它们都非常相似,我觉得应该有一种方法可以批量提交它们。我能找到的示例显示批量更新不允许像我需要的那样对每个更新设置单独的限制


您知道有什么方法可以加快此过程吗?

以下方法依赖于以下事实:Occessions表有一个主键,citizen\u id不是主键的一部分。我的想法是:

将要筛选的update citizen_id和good_id的所有参数、citizen_id的新值和要更新的行数放入某个存储器、专用表或临时表中

将行号分配给citizen_id、good_id上的财产行分区,然后将已排序的行集加入参数表,以过滤citizen_id和good_id上的原始完整集,以及行数

在主键值上连接属性和上一次连接的结果,并用新值更新citizen_id

在MySQL的SQL中,上面可能是这样的:

UPDATE possessions SET citizen_id=1 WHERE citizen_id=2 AND good_id=8 LIMIT 1
UPDATE possessions SET citizen_id=2 WHERE citizen_id=4 AND good_id=2 LIMIT 1
UPDATE possessions SET citizen_id=4 WHERE citizen_id=3 AND good_id=5 LIMIT 2
UPDATE possessions AS p
INNER JOIN
(
  SELECT
    @r := @r * (@c = p.citizen_id AND @g = p.good_id) + 1 AS r,
    p.possession_id,
    @c := p.citizen_id AS citizen_id,
    @g := p.good_id AS good_id
  FROM
    possessions AS p
  CROSS JOIN
    (SELECT @r := 0, @c := 0, @g := 0) AS x
  ORDER BY
    p.citizen_id,
    p.good_id
) AS f ON p.possession_id = f.possession_id
INNER JOIN
  possession_updates AS u ON u.citizen_id = f.citizen_id AND u.good_id = f.good_id
SET
  p.citizen_id = u.new_citizen_id
WHERE
  f.r <= u.row_count
;
U更新是包含参数值的表

查询使用一种已知的行编号方法,该方法使用变量,该方法在f子查询中实现


我没有MySQL,所以我无法从性能的角度对其进行适当的测试,但至少你可以从中看出该方法是有效的。UPDATE语句位于模式脚本中,因为SQL FIDLE不允许在MySQL的右侧脚本中使用数据修改语句。右侧仅返回物品更新后的内容。

您想要并行更新吗?因为有些场地会和一些场地比赛。如果在不使用任何临时数据的情况下对原始数据执行这些操作,则这可能是未定义的行为。mysql可以在不硬横跨多个查询的情况下进行并行更新吗?使用临时表不是不可能的。我只是想在更新的次数达到数百或数千次时,寻找一些东西来加速这个过程。这些查询是在单个子函数调用中进行的吗?或者你是在一个接一个地发送它们吗?目前,我找到的唯一方法是在中提供正确的结果,以便一个接一个地提交这些查询。你没有使用ORDER by和你的限制,这意味着你将首先更新匹配的任何行。这是故意的吗?此外,过滤器是否始终在公民id和良好id上?最后,您的示例包括两个LIMIT 1更新和一个LIMIT 2更新。这是打字错误还是限制也可能不同?