【问题标题】:How to optimize MySQL UPDATE如何优化 MySQL UPDATE
【发布时间】:2012-05-22 11:47:47
【问题描述】:

请问有什么办法可以优化MySql中的这个更新查询吗?

   UPDATE table1 t1 
   SET t1.column = 
   (SELECT MIN(t2.column) 
     FROM table2 t2 WHERE t1.id = t2.id
    );

两个表都有大约 250 000 条记录。

表结构:

CREATE TABLE `table1` (
 `id` int(11) NOT NULL,  
 `column` datetime NOT NULL,
 PRIMARY KEY (`id`)  
) ENGINE=InnoDB DEFAULT CHARSET=utf8

CREATE TABLE `table2` (
 `code` int(11) NOT NULL,  
 `id` int(11) NOT NULL,    
 `column` datetime NOT NULL,
 PRIMARY KEY (`code, `id`)  
) ENGINE=InnoDB DEFAULT CHARSET=utf8

ALTER TABLE table2 ADD CONSTRAINT FK_id 
    FOREIGN KEY (id) REFERENCES table1 (id)         
;

感谢您的帮助。

【问题讨论】:

  • id 是主键吗(在两个表中)?
  • yes ..in table1是主键只是id,在table2有复合主键包含idtable1 的外键

标签: mysql sql query-optimization


【解决方案1】:

我会这样做:

创建一个临时表来保存聚合值

CREATE TEMPORARY TABLE tmp_operation 
SELECT id, MIN(`column`) as cln FROM table2 GROUP BY id;

为临时表添加索引以更快地连接到表 1(可以根据数据大小省略此步骤)

ALTER TABLE tmp_operation ADD UNIQUE INDEX (id);

使用简单连接进行更新。您可以使用左连接或内连接,具体取决于您是否要将列更新为空值)

UPDATE table1 
SET table1.`column` = tmp_operation.cln
INNER JOIN tmp_operation ON table1.id = tmp_operation.id;

完成后删除临时表

DROP TABLE tmp_operation;

【讨论】:

  • 太棒了!这更快。非常感谢您的帮助:)
【解决方案2】:

您可以通过首先分组表t2 然后使用JOIN 来做到这一点(这类似于@frail 的答案,但没有临时表):

UPDATE 
      table1 t1 
  JOIN
      ( SELECT id
             , MIN(column) AS min_column
        FROM table2 
        GROUP BY id
      ) AS t2
    ON t2.id = t1.id
SET t1.column = t2.min_column ;

table2(id, column) 上的索引将有助于提高性能。

【讨论】:

  • @Daniel:请告诉我们,您实际上并没有使用这些 tablecolumn 名称,它们只是隐藏了您真正明智的名称。
  • 不错。我很想看看性能与脆弱的答案相比如何。此解决方案无法为 JOIN 使用索引,但仍会使用二分搜索,如果结果集不太大,由于开销较小,这可能会更快。
【解决方案3】:

在table1主键的table2中添加外键

UPDATE table1 t1
INNER JOIN table2 t2
ON t1.id = t2.id
SET t1.column = t2.column
having MIN(t2.column)

examples

【讨论】:

  • thanx 但我得到了:#1111 - 组函数的使用无效
  • 请您分享表格结构/脚本吗?
  • 你可以在最后一次使用有子句,即有 min(t2.column)
  • 这个查询没有任何意义,但是thanx :) ....... #1064 - 你的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 5 行的“具有 MIN(t2.column)”附近使用正确的语法
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-03
  • 2013-03-07
相关资源
最近更新 更多