Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I optimize MySQL query for update?

I have a table with 300 000 records. In this table have duplicae rows and I want to update column "flag"

TABLE

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

I use this query for updating "flag" column:

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'

This query working very very slowly (more 600 seconds) for this 300 000 records.

How Can I optimize this query?

STRUCTURE OF MY TABLE

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 ;

If "name" is duplicate I want to update flag_qty

like image 387
dido Avatar asked Mar 14 '12 09:03

dido


1 Answers

If you do not already have an index on number you should add one -

CREATE INDEX table_number ON table (number);

UPDATE Try this -

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

You can create your table with just the duplicates by selecting this data directly into another table instead of doing this flag update first.

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

If you can explain the logic for which rows get deleted from inv table it may be that the whole process can be done in one step.

like image 153
nnichols Avatar answered Sep 28 '22 10:09

nnichols