This topic was marked solved by its starter, on April 21st, 2013, 12:56 PM

Nao

  • Dadman with a boy
  • Posts: 16,082
Member recount
« on April 20th, 2013, 05:28 PM »
I was trying to recount members on my local install, which has the Wedge.org member database, but without any posts.
It turns out that, from looking at the source code, it first gets a list of members, then counts how many posts they have in the message table, then updates their counts.
However, if a user has no message at all in the table, their account will simply be ignored...

Two possible solutions:

- Set all members to 0 posts at the start of the process. Would make sense... Especially since this is already there as a 'fallback' for a strange reason.
- Load all message count entries into the member list, i.e. $members = array(member 1 => 65 posts, 2 => awaiting count, ...), and then after we're done counting, update all members one by one.

I would fix that myself, but as I know that @Arantor rewrote this a while ago, I'm wary of breaking anything.

Hmmm... Nice bug in mentions... I just typed @Arantor, and it showed me a loooong list of 'Arantor' names in the list... It's possibly due to Ajax being slow for me here, so it's getting multiple requests sent before even receiving them.

ziycon

  • Posts: 126
Re: Member recount
« Reply #1, on April 20th, 2013, 07:23 PM »
I wouldn't use the first option as you will end up executing two update statements for each user which is a slight bit more cpu intensive then a single query unless you have a reason for running two queries.

The second option seems better, count all posts based on user ID into an array and then run an update statement when the value in the array is greater then the value in the user post count filed.

Or you could use a single query to update all users similar to the below query.
Code: [Select]
UPDATE {user_table}
SET {post_count}=(
SELECT COUNT({post_id})
FROM {post_table}
WHERE {user_id_field}={user_id}
)
WHERE {user_id_field}={user_id};
APRAI - Custom Theme - SMF 2.0.5


Nao

  • Dadman with a boy
  • Posts: 16,082
Re: Member recount
« Reply #2, on April 20th, 2013, 07:56 PM »
Quote from ziycon on April 20th, 2013, 07:23 PM
I wouldn't use the first option as you will end up executing two update statements for each user
How so..? UPDATE {db_prefix}members SET posts = 0. That's it... A single query for ALL members.
Quote
The second option seems better, count all posts based on user ID into an array and then run an update statement when the value in the array is greater then the value in the user post count filed.
Well, yes we could also store the original count, and only update if it's different (not higher...), that's for sure.
Quote
Or you could use a single query to update all users similar to the below query.
Code: [Select]
UPDATE {user_table}
SET {post_count}=(
SELECT COUNT({post_id})
FROM {post_table}
WHERE {user_id_field}={user_id}
)
WHERE {user_id_field}={user_id};
It'd be slightly more complex than this one, but generally speaking, I'd avoid using subselects because they're rarely faster than multiple well-optimized queries.

ziycon

  • Posts: 126
Re: Member recount
« Reply #3, on April 20th, 2013, 08:21 PM »
Quote from Nao on April 20th, 2013, 07:56 PM
How so..? UPDATE {db_prefix}members SET posts = 0. That's it... A single query for ALL members.
You're correct in what you said, it's been a long day an I had it in my head that you'd be using a loop in the code to go through each user.
Quote
Well, yes we could also store the original count, and only update if it's different (not higher...), that's for sure.
Do you store user data in the cache, could you check the recount against the cached information or is the cache reliable enough to trust?
Quote
Or you could use a single query to update all users similar to the below query.
Code: [Select]
UPDATE {user_table}
SET {post_count}=(
SELECT COUNT({post_id})
FROM {post_table}
WHERE {user_id_field}={user_id}
)
WHERE {user_id_field}={user_id};
It'd be slightly more complex than this one, but generally speaking, I'd avoid using subselects because they're rarely faster than multiple well-optimized queries.
I know it would be more complex was just a basic example. Point taken, individual queries could use and index for quicker execution time.

Nao

  • Dadman with a boy
  • Posts: 16,082
Re: Member recount
« Reply #4, on April 21st, 2013, 12:56 PM »
(fixed in my r2066...)