did*_*ido 6 mysql optimization
我有一张有300 000条记录的表格.在这个表有duplicae行,我想更新列"标志"
表
------------------------------------
|number | flag | ... more column ...|
------------------------------------
|ABCD | 0 | ...................|
|ABCD | 0 | ...................|
|ABCD | 0 | ...................|
|BCDE | 0 | ...................|
|BCDE | 0 | ...................|
Run Code Online (Sandbox Code Playgroud)
我使用此查询更新"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'
Run Code Online (Sandbox Code Playgroud)
对于这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 ;
Run Code Online (Sandbox Code Playgroud)
如果"name"是重复的,我想更新flag_qty
如果您还没有索引,number则应该添加一个 -
CREATE INDEX table_number ON table (number);
Run Code Online (Sandbox Code Playgroud)
更新试试这个 -
UPDATE inv t1
INNER JOIN inv t2
ON t1.name = t2.name
AND t1.id <> t2.id
SET t1.flag_qty = 1;
Run Code Online (Sandbox Code Playgroud)
您可以通过直接选择此数据到另一个表中来创建仅包含重复项的表,而不是首先执行此标志更新。
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
Run Code Online (Sandbox Code Playgroud)
如果您可以解释从表中删除行的逻辑,inv那么整个过程可能可以一步完成。