Mysql update语句中不存在需要更多时间

Mysql update语句中不存在需要更多时间,mysql,sql,sql-update,Mysql,Sql,Sql Update,在MySQL中 update table1 t1 set column1 = 100, column2 = 200 where column3 > 500 and not exists(select * from table2 where column1 = t1.column1); 此查询太耗时,无法执行,是否有其他更快的重写方法 对于table2,ID是一个主列,所以我想

在MySQL中

update table1 t1 
   set column1 = 100,
       column2 = 200
 where column3 > 500 
   and not exists(select * 
                    from table2 
                   where column1 = t1.column1);
此查询太耗时,无法执行,是否有其他更快的重写方法

对于table2,ID是一个主列,所以我想我可以重写为

update table1 t1 
   set column1 = 100,
       column2 = 200
 where column3 > 500 
   and not exists(select ID 
                   from table2  
                  where column1 = t1.column1);

但查询仍然需要2秒才能运行,我希望以毫秒为单位。

使用Not exists时,查询处理器一旦找到一行,它就可以停止,但如果该行确实不存在,那么它必须检查整个表中子查询中定义的列,然后才能确定该行不存在。。。因此,如果子查询中有任何过滤器,那么唯一的加速方法就是在这些列上放置一个或多个索引。在您的情况下,这意味着表2.1中有一个索引

使用联接可能没有帮助,因为无论它是联接子查询还是不存在子查询,查询处理器都必须执行相同的逻辑IOs来处理数据

要使用连接,我不确定MySql的语法,它可能是:p

UPDATE TABLE1 SET
     column1 = 100, 
     column2 = 200 
  From Table1 t1
      Left Join TABLE2 t2 
          ON t2.column1 = t1.column1 
  WHERE t2.column1 Is Null


使用Not exists时,查询处理器一找到行就可以停止,但如果该行确实不存在,那么它必须检查整个表中子查询中定义的列,然后才能确定该行不存在。。。因此,如果子查询中有任何过滤器,那么唯一的加速方法就是在这些列上放置一个或多个索引。在您的情况下,这意味着表2.1中有一个索引

使用联接可能没有帮助,因为无论它是联接子查询还是不存在子查询,查询处理器都必须执行相同的逻辑IOs来处理数据

要使用连接,我不确定MySql的语法,它可能是:p

UPDATE TABLE1 SET
     column1 = 100, 
     column2 = 200 
  From Table1 t1
      Left Join TABLE2 t2 
          ON t2.column1 = t1.column1 
  WHERE t2.column1 Is Null


请尝试不使用相关子查询的方法:

UPDATE Table1
   SET Column1 = 100, Column2 = 100
 WHERE Column3 > 500
   AND Column1 NOT IN (SELECT Column1 FROM Table2);

请尝试不使用相关子查询的方法:

UPDATE Table1
   SET Column1 = 100, Column2 = 100
 WHERE Column3 > 500
   AND Column1 NOT IN (SELECT Column1 FROM Table2);
请尝试以下方法:

   UPDATE TABLE1 
LEFT JOIN TABLE2 ON TABLE2.column1 = TABLE1.column1
                AND TABLE2.column2 IS NULL 
      SET column1 = 100,
          column2 = 200
    WHERE TABLE2.column1 IS NULL
      AND column3 > 500 
请尝试以下方法:

   UPDATE TABLE1 
LEFT JOIN TABLE2 ON TABLE2.column1 = TABLE1.column1
                AND TABLE2.column2 IS NULL 
      SET column1 = 100,
          column2 = 200
    WHERE TABLE2.column1 IS NULL
      AND column3 > 500 

它正在更新多少记录?表1:200K表2:150K记录。它正在更新多少记录?表1:200K表2:150K记录。谢谢,你能帮助我如何将上述查询加入,我无法正确获取它。所以你的意思是说外部连接会降低耗时。添加了sql for join,但我不熟悉mysql语法,所以这些可能不完全正确…谢谢,你能帮我如何将上述查询放入连接中,我无法获得正确的结果。所以你的意思是说外部连接将减少耗时。添加了sql for join,但我不熟悉mysql语法,所以这些可能不完全正确…感谢OMG Ponies。我很接近,实际上我在not exists语句中错过了这个条件,not exists从表2中选择ID,其中column1=t1.column1,column2为null;我需要添加这个,否则它会更新所有记录。谢谢,但这是我的查询更新table1 t1 set column1=100,column2=200,其中column3>500且不存在从table2中选择*,其中column1=t1.column1和column2为空;上面这句话是不是不存在?@Sharpeye500:我错过了第3栏的比较-更正。否则,NOT IN、NOT EXISTS和LEFT JOIN/IS NULL是等效的-如果比较的列不能为NULL,则唯一的区别是LEFT JOIN/IS NULL在MySQL上更有效,即:column1。否则,NOT IN或NOT EXIST性能会更好。谢谢,第一个表的更新应该针对未从此语句检索到的记录。请从表2中选择*,其中column1=t1。column1和column2为null。在上述情况下,你在哪里告诉这些记录不被考虑,我猜你是加入两者,对不起,如果我傲慢,你可以请。告诉我如何将not in转换为保持相同功能的联接。@Sharpeye500:此部分:TABLE2.column1为NULL是过滤掉不需要的记录的原因-如果左联接中没有匹配项,则TABLE2列值将为NULL。因此,您可以在WHERE子句中使用它来删除符合连接条件的行。感谢OMG Ponies。我很接近,实际上我在not exists语句中错过了这个条件,not exists从表2中选择ID,其中column1=t1.column1,column2为null;我需要添加这个,否则它会更新所有记录。谢谢,但这是我的查询更新table1 t1 set column1=100,column2=200,其中column3>500且不存在从table2中选择*,其中column1=t1.column1和column2为空;上面这句话是不是不存在?@Sharpeye500:我错过了第3栏的比较-更正。否则,NOT IN、NOT EXISTS和LEFT JOIN/IS NULL是等效的-如果比较的列不能为NULL,则唯一的区别是LEFT JOIN/IS NULL在MySQL上更有效,即:column1。否则,NOT IN或NOT EXIST性能会更好。谢谢,第一个表的更新应该针对未从此语句检索到的记录。请从表2中选择*,其中column1=t1。column1和column2为null。在上面的例子中,你告诉我这些记录不被考虑,我猜你是同时加入了这两个角色 ,对不起,如果我傲慢,你能帮我吗。告诉我如何将not in转换为保持相同功能的联接。@Sharpeye500:此部分:TABLE2.column1为NULL是过滤掉不需要的记录的原因-如果左联接中没有匹配项,则TABLE2列值将为NULL。因此,您可以在WHERE子句中使用它来除去符合联接条件的行。