Domanda

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?

È stato utile?

Soluzione

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);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top