Chasefornone
Chasefornone

Reputation: 757

Mysql update statement executes too slowly

There are two tables as follows in my problem.

CREATE TABLE `t_user_relation` (
  `User_id` INT(32) UNSIGNED NOT NULL  ,
  `Follow_id` INT(32) UNSIGNED NOT NULL ,
  PRIMARY KEY (`User_id`,Follow_id)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

CREATE TABLE `t_user_info`(
    `User_id` int(32) unsigned NOT NULL  ,
    `User_name` varchar(20) NOT NULL ,
    `User_avatar` varchar(60) NOT NULL ,
    `Msg_count` int(32) unsigned DEFAULT '0' ,
    `Fans_count` int(32) unsigned DEFAULT '0' ,
    `Follow_count` int(32) unsigned DEFAULT '0' ,
    PRIMARY KEY (`User_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

What I am trying to do is to update the Fans_count filed of the t_user_info table. My update statement is as follows:

 UPDATE t_user_info set t_user_info.Fans_count=(SELECT COUNT(*) FROM t_user_relation
 WHERE t_user_relation.Follow_id=t_user_info.User_id);

But it execute really slow! The table t_user_info consist of 20,445 records and t_user_relation consist of 1,809,915 records.Can anyone help me improve the speed! Thanks for any advices!

Upvotes: 0

Views: 89

Answers (2)

fthiella
fthiella

Reputation: 49089

I would try this:

UPDATE
  t_user_info inner join
  (SELECT Follow_id, COUNT(*) as cnt
   FROM t_user_relation
   GROUP BY Follow_id) s
  on t_user_info.User_id=s.Follow_id
SET t_user_info.Fans_count=s.cnt

I'm using a subquery to calculate the count of rows for every Follow_id in table t_user_relation:

SELECT Follow_id, COUNT(*) as cnt
FROM t_user_relation
GROUP BY Follow_id

I am then joining the result of this query with t_user_info, and I am updating Fans_count where the join succeeds, setting it to the count calculated in the subquery.

A query written like this usually runs faster because the resulting rows from the subquery are calculated only once, before the join, while in your solution your subquery is calculated once for every user row.

Upvotes: 3

bobthyasian
bobthyasian

Reputation: 943

When dealing with a large number of records on a DB you want to stay away from the wildcard (*) and utilize indexes.

Upvotes: 2

Related Questions