【问题标题】:How to insert only one column from one table to a multi-columned table?如何从一张表中只插入一列到多列表中?
【发布时间】:2018-11-01 14:37:58
【问题描述】:

我在使用 INSERT 到表时遇到了一些问题。基本上,我运行我的插入命令,我得到:

错误代码 2013:在查询期间丢失与 MySQL 服务器的连接。

这是我的插入命令:

INSERT IGNORE INTO t1(a_id, b_id, c_id, d_id, e_id)
SELECT t1 a_id, b_id, c_id, d_id, e_id FROM all_data;

对于这个问题,我尝试增加连接超时时间。

但是,之后我得到:

超过锁定等待超时;尝试重启事务

我已经尝试杀死所有可能的进程。没有任何成功。更不用说如果你增加超时时间,那么查杀过程的执行时间可能是查询执行时间的 30 倍。

我认为我对这个问题的解决方案是尝试一次添加更少的数据。因此,我的问题是如何将一列插入到多列表中?

TL;DR:

问题 1: 由于“查询期间丢失与 MySQL 服务器的连接”,插入命令失败

我的解决方案:增加连接超时时间。

问题 2: 由于“超出锁定等待超时”,插入命令失败。

我的解决方案:杀死进程。之后尝试一次添加一列。

我的最后一个问题:如何仅将另一表中的一列插入到多列表中?例如

INSERT IGNORE INTO t1(a_id, b_id, c_id, d_id, e_id)
SELECT a_id FROM all_data;

【问题讨论】:

  • 这里似乎有两个问题,除非我误解了。 1) 为什么插入会死锁或超时,以及 2) 如何只将一个值插入到具有多列的表中。
  • INSERT INTO t1(a_id) SELECT a_id FROM all_data; 但我认为你有一个更大的问题要解决。我只是无法想象这会有所帮助。为什么要超时?
  • @JacobH 你是对的。但是,我对其他表使用了相同的方法,即使列比这个多。我一直无法找出为什么我会陷入僵局。因此,我认为我应该尝试这种方法,我不知道它是否可行。
  • @JNevill 如果我运行它,我会得到“错误 1364:字段 'b_id' 没有默认值”。有没有解决的办法 ?如果我添加 IGNORE 会有帮助吗?
  • 你完全可以在里面硬编码一些东西INSERT INTO t1(a_id, b_id, c_id, d_id, e_id) SELECT a_id, 0,0,0,0,0 FROM all_data;(我假设这些都是数字/整数)

标签: mysql sql mysql-workbench


【解决方案1】:

如何在多列表中只插入一列?

长时间处理和锁定等待超时问题很可能来自处理太多行而不是太多列。因此,一次插入一列并不能解决您的问题。

您一次需要处理更少的行。在不知道您的 all_data 表是否有主键的情况下,很难就此给出具体建议。但是,假设您有一个名为 primary_key_id 的主键列,下面是该过程的概要。

 SET @last_id := -1;

 INSERT IGNORE INTO t1( a_id, b_id, c_id, d_id, e_id)
 SELECT a_id, b_id, c_id, d_id, e_id 
   FROM all_data
  WHERE primary_key_id > @last_id
  ORDER BY primary_key_id
  LIMIT 1000

 SELECT MAX(primary_key_id) INTO @last_id 
   FROM all_data
  WHERE primary_key_id > @last_id
  ORDER BY primary_key_id
  LIMIT 1000

然后重复第二个和第三个查询,直到第二个查询没有插入任何行。

我已将1000 设置为批量大小。您也许可以使用更大或更小的东西。

如果您不能使用主键,您可以考虑以其他方式拆分批次。也许,例如,通过名字的第一个字母。第一批将使用WHERE name LIKE '%A' 检索,第二批将使用WHERE name LIKE '%B' 检索,依此类推。你知道你的数据,所以你是弄清楚如何分解你的批次的人。

【讨论】:

  • 谢谢,这很有见地。我没有想到我可能需要减少行而不是列。但是, all_data 没有主键。还有其他方法可以解决这个问题吗?
  • 主键只是一种在插入中处理批量数据的便捷方式。您可以使用a_id BETWEEN 0 AND 999a_id BETWEEN 1000 AND 1999 等创建批次。
  • 道歉,但我不确定我是否遵循。仅当我的 id 以数字开头时,这才有效吗?
【解决方案2】:

尝试在插入之前运行此isolation-level command,以告诉 MySQL 在 all_data 表忙时不要等待。

 SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

【讨论】:

    猜你喜欢
    • 2013-12-15
    • 1970-01-01
    • 2019-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多