Reputation: 707
I am effecting 50,000+ updates on a MySQPL table fairly frequently. I tried it this way:
UPDATE data SET p=p+(13) where c=2 and g=12
UPDATE data SET p=p+(17) where c=3 and g=41
UPDATE data SET p=p+(-12) where c=6 and g=19
UPDATE data SET p=p+(-4) where c=8 and g=12
...
As you might imagine, it takes a while. I measure it at about 45 sec. So, I tried creating a temp table so I could get the same work done in less queries. That looks like this:
CRATE TEMPORARY TABLE changes(
id INT AUTO_INCREMENT,
g INT,
c INT,
delta_p INT,
PRIMARY KEY (id)
)
INSERT INTO changes(g,c,delta_p) VALUES (12,2,13),(41,3,17),(19,6,-12),(12,8,-4)...
UPDATE p INNER JOIN changes AS c ON p.c=c.c AND p.g=c.g SET p.p=p.p+c.delta_p
DROP TABLE changes
I liked this solution at first because I was under the assumption that less queries would almost always be faster. I thought cutting down from 50,000 queries to 4 would make a difference. What I observe, however, is that it is about 10x slower. I measured the second method at 500 sec.
I really want to know how to speed this up, but my question here is: Why is the second method so much slower? Can anyone give me some insight into why I'm seeing this behavior?
Upvotes: 0
Views: 44
Reputation: 1269743
You need an index on the changes
table:
create index changes_c_g on changes(c, g);
This will speed up the join
a lot. A covering index would help even more:
create index changes_c_g_deltap on changes(c, g, delta_p);
Upvotes: 1