如何优化MySQL查询以进行更新?

时间:2012-03-14 09:16:23

标签: mysql optimization

我有一张有300 000条记录的表格。在此表中有duplicae行,我想更新列“flag”

------------------------------------
|number | flag | ... more column ...|
------------------------------------
|ABCD   |  0   | ...................|
|ABCD   |  0   | ...................|
|ABCD   |  0   | ...................|
|BCDE   |  0   | ...................|
|BCDE   |  0   | ...................|

我使用此查询更新“flag”列:

UPDATE table i 
INNER JOIN (SELECT number FROM table
            GROUP BY number HAVING count(number) > 1 ) i2
ON i.number = i2.number
SET i.flag = '1'

对于这300 000条记录,此查询的工作速度非常慢(超过600秒)。

如何优化此查询?

我的表的结构

CREATE TABLE IF NOT EXISTS `inv` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `pn` varchar(10) NOT NULL COMMENT 'Part Number',
  `qty` int(5) NOT NULL,
  `qty_old` int(5) NOT NULL,
  `flag_qty` tinyint(1) NOT NULL,
  `name` varchar(60) NOT NULL,
  `vid` int(11) NOT NULL ,
  `flag_d` tinyint(1) NOT NULL ,
  `flag_u` tinyint(1) NOT NULL ,
  `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `pn` (`pn`),
  KEY `name` (`name`),
  KEY `vid` (`vid`),
  KEY `pn_2` (`pn`),
  KEY `flag_qty` (`flag_qty`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=0 ;

如果“name”重复,我想更新flag_qty

3 个答案:

答案 0 :(得分:3)

如果您还没有number的索引,则应添加一个 -

CREATE INDEX table_number ON table (number);

更新试试这个 -

UPDATE inv t1
INNER JOIN inv t2
    ON t1.name = t2.name
    AND t1.id <> t2.id
SET t1.flag_qty = 1;

您可以通过直接在另一个表中选择此数据而不是首先更新此标志来创建仅包含重复项的表。

INSERT INTO duplicate_invs
SELECT DISTINCT inv1.*
FROM inv AS inv1
INNER JOIN inv AS inv2
    ON inv1.name = inv2.name
    AND inv1.id < inv2.id

如果您可以解释从inv表中删除哪些行的逻辑,则可能只需一步即可完成整个过程。

答案 1 :(得分:1)

获取MySQL EXPLAIN查询给你。然后你会看到索引会改进什么。

答案 2 :(得分:1)

EXPLAIN会告诉你哪里它很慢,这里有一些想法,如何来提高性能:

  • 添加索引
  • 使用InnoDB外键
  • 将查询拆分为2并在您使用的lagnuage中单独处理它们。
  • 在MySQL程序中写出相同的想法(不确定,这是否会很快)。