具有限制的MySQL批量查询

时间:2014-02-18 05:50:02

标签: 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=4 WHERE citizen_id=3 AND good_id=5 LIMIT 2

有些时候,有很多这些,它们都非常相似,我觉得应该有一种方法可以批量提交它们。我可以找到显示批量更新的示例,不允许像我需要的那样为每个更新设置个别限制。

您是否知道我可以更快地完成此过程?

1 个答案:

答案 0 :(得分:0)

以下方法依赖于possessions表具有主键且citizen_id不属于它的事实。这是个主意:

  1. 将更新的所有参数(citizen_idgood_id过滤,将citizen_id的新值和要更新的行数)放入某个存储中,也许是一张专用的桌子或临时桌子。

  2. 将行号分配给possessions上分区的(citizen_id, good_id)行,然后将排名的行集加入参数表,以过滤citizen_id和{{1}上的原始完整集},以及行数。

  3. 加入good_id以及上一次加入主键值的结果,并使用新值更新possessions

  4. 在MySQL的SQL中,上面的内容可能如下所示:

    citizen_id

    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 ; 是包含参数值的表。

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

    我没有MySQL,所以从性能的角度来看,我无法正确测试,但至少你可以从this SQL Fiddle demo看到该方法有效。 (UPDATE语句位于模式脚本中,因为SQL Fiddle不允许在MySQL的右侧脚本中使用数据修改语句。右侧只返回f的更新后内容。)