سؤال

I store top-views and 'likes' in a table called 'counts'. Once a night I run this query

UPDATE `counts` SET rank=d7+d6+d5+d4+d3+d2+d1,d7=d6,d6=d5,d5=d4,d4=d3,d3=d2,d2=d1,d1=0

Each day of the week has a d1-d7 variable, and we move it 'down' one each night and re-calculate the sum.

As my site has grown, this query now takes ~20 minutes.

I'm looking for suggestions on how to organize this more efficiently, as it seems like it might be a common pattern.

هل كانت مفيدة؟

المحلول

As the comments say, we need to see the schema. But I'll make a suggestion anyway. Don't have 7 different fields d1-d7. What if later you decide to keep the score over a year? Ouch.

I'm going to assume that counts has view_id as its PK. Then have another table ranks with columns view_id (set as FK into counts), rank (generalizes d1-d7, whatever datatype they are) and rank_date, which is a date. Now every night you have

UPDATE counts SET rank = (SELECT SUM(rank) FROM ranks r WHERE r.view_id=counts.view_id
                        AND r.rank_date>=DATE_SUB(CURDATE(), INTERVAL 1 WEEK) );

[Some RDBMSs allow a JOIN-type syntax in UPDATE queries. I believe MySQL understands something similar to the following, but it isn't my usual RDBMS

UPDATE counts, (SELECT view_id, SUM(rank) AS srank FROM ranks r 
                WHERE  r.rank_date>=DATE_SUB(CURDATE(), INTERVAL 1 WEEK) 
                GROUP BY r.view_id) AS q1 
SET rank = srank
WHERE counts.view_id=q1.view_id;   

]

If so, that will probably run faster than the first version.

Meanwhile, optionally to clean up, you can delete rows from ranks that are more than 1 week old, but in a more flexible schema, you don't have to.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top