【问题标题】:MySQL - Updating a selection with iterative integersMySQL - 使用迭代整数更新选择
【发布时间】:2020-04-24 06:30:58
【问题描述】:

你好,互联网书呆子!

技术上我已经解决了这个问题,但想知道我是否应该采取更优化的路线......

我有一个大表(约 4m 行),它是一个数据集合,使用 int "chip" 进行分段。有 6 段数据,所以芯片 ID 为 1 到 6。

在这 6 个段中,我需要分配一个 order 整数,它需要是迭代的,因为它表示数据在所述段上的确切位置。

我的解决方案是(曾经)是这样的:

# set iterative
set @i:=0;

# init
update table set `order` = @i:=(@i+1) where chip = 1;

这行得通。但它太慢了,有时会触发超时错误。我需要运行它 6 次,它可能会在必要时由我们的应用程序偶尔触发。也许只是我需要更多的时间来设置 MySQL 来解决缓慢的查询,或者是否有一个最佳的、更简单的解决方案?

感谢您的建议。

编辑:

我找到了一个准确的解决方案,大约需要 50 秒才能完成。

我现在使用在更新中配对的有序选择语句,使用在列中迭代的生成的连接表。

见:

set @count:= 0;
update 
table as target,
    (select 
    (@count :=  @count+1) as row_num,
    t.*
    from table as t
    where chip = 1
    order by t.id asc) as table_with_iterative
set target.`order` = table_with_iterative.row_num
where target.id = table_with_iterative.id; 

【问题讨论】:

  • 这行得通 形式上它是随机排序的。 太慢了 什么是执行时间? 有没有最佳的、更简单的解决方案?指定 MySQL 版本并显示表的 DDL。
  • @Akina 我猜“这么慢”意味着它打破了我默认的 15 秒运行时间。我预计它必须在某个范围内徘徊。我可以添加一个临时的 lock_timeout 设置来修复吗?这对我来说就像一个补丁,但我想这样做没有错吗?

标签: mysql database algorithm optimization bigdata


【解决方案1】:

我认为,如果可能,您应该在第一次将行插入表中时分配序列号。严格来说,SQL 数据库不保证行最初会按照INSERT 语句的顺序出现在表中。

我想到的一种可能性是在此表中使用自动递增字段,因为这表示添加行的顺序。但是,任何给定 chip 的字段值虽然是递增的,但可能不是连续的,并且无疑不会从 1 开始。

如果您确实需要这样的字段,我想我会定义一个单独的字段(默认值:NULL)来保存它。然后,一个非常简单的存储过程可以查询给定芯片的行(ORDER BY自动递增编号),并为该单独字段分配一个从 1 开始的连续序列号。 (稍微复杂一点的查询可以识别出所有还没有这些数字的列表,并立即对它们进行编号。)

【讨论】:

    【解决方案2】:

    我找到了一个准确有效的解决方案,大约需要 50 秒才能完成。

    这会处理我遇到的无序更新。

    我现在使用在更新语句中配对的有序选择语句,使用在 row_num 列中迭代的生成连接表。

    见:

    set @count:= 0;
    update 
    table as target,
        (select 
        (@count :=  @count+1) as row_num,
        t.*
        from table as t
        where chip = 1
        order by t.id asc) as table_with_iterative
    set target.`order` = table_with_iterative.row_num
    where target.id = table_with_iterative.id; 
    

    【讨论】:

      猜你喜欢
      • 2019-01-11
      • 2011-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-24
      • 1970-01-01
      • 2017-03-14
      相关资源
      最近更新 更多