Question

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?

Was it helpful?

Solution

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);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top