3

I have a custom script for a bulletin board system that counts the number of threads a user has made, and updates a column accordingly. This works fine, however with 100,000+ users, it times out when running it for the first time.

I've tried adding the following before the query, but it still times out (500 error).

set_time_limit(0);
ignore_user_abort(true);

Additional: I'm using this script on my vps.

Query:

set_time_limit(0); 
ignore_user_abort(true);

$db->write_query("ALTER TABLE `".TABLE_PREFIX."users` ADD `numthreads` int(10) unsigned NOT NULL default '0'");

// load users into an array to count number of threads
$query = $db->simple_select("users", "uid");
while($user = $db->fetch_array($query))
{
    $users[$user['uid']] = $user;
}

foreach($users as $user)
{   
    $query = $db->simple_select("threads", "COUNT(tid) AS threads", "uid = '{$user['uid']}'");

    // get total number of threads
    $numthreads = intval($db->fetch_field($query, "threads"));

    $db->update_query("users", array("numthreads" => $numthreads), "uid = '{$user['uid']}'");
}
13
  • Have you tried put the code at the beginning of your script? Commented Aug 24, 2011 at 3:13
  • can you share the code? is your DB optimized? Commented Aug 24, 2011 at 3:14
  • Is there any information you can provide then just 500 error (some text it is showing would help)? Are you on a shared environment? Commented Aug 24, 2011 at 3:14
  • I have the user's table set to InnoDB...and I'm on a VPS. As for the 500 error, there's not much of an error text as Chrome doesn't provide any. Commented Aug 24, 2011 at 3:16
  • can you share the queries? db/table structure? Commented Aug 24, 2011 at 3:17

4 Answers 4

7

Use this:

ini_set('max_execution_time', 0);

Inplace of:

set_time_limit(0); 
ignore_user_abort(true);

You can also edit php.ini:

max_execution_time = 60; //Maximum execution time of each script, in seconds
max_input_time = 60; //Maximum amount of time each script may spend parsing request data

Hope this helps.

Sign up to request clarification or add additional context in comments.

Comments

6

First you should separate your ALTER statement. Execute the ALTER first and then do the rest. Alter table can be expensive in time if you have a big table. You can run it manually, using phpmyadmin or via shell (even better since there's no php timeout). which will give you the ability to not timeout.

Then remove the ALTER from the script and run it.

and then use:

$query = $db->simple_select("users", "uid");
while($user = $db->fetch_array($query))
{
    $query = $db->simple_select("threads", "COUNT(tid) AS threads", "uid = '{$user['uid']}'");

    $numthreads = intval($db->fetch_field($query, "threads"));
    $db->update_query("users", array("numthreads" => $numthreads), "uid = '{$user['uid']}'");
}

6 Comments

I'd prefer to keep the ALTER statement in the script, as this is a plugin I'll be sharing with a few others, so they'll essentially need the ALTER statement.
It contains about 110,000 records.
when you execute the script and you get the time out, does the ALTER statement is completed? or you still have the old structure (without the numthreads column)?
The ALTER statement is completed...it just times out when attempting to count the number of threads and update accordingly.
see my comment in the propose solution. you are looping twice there, only one is needed.
|
2

try this

ini_alter ("max_execution_time", 600000000);
$tmp = ini_get ( "max_execution_time" );
set_time_limit(600000000);

1 Comment

Unfortunately, your suggested code doesn't work either...it still times out.
0

A common reason that people are not able to change the max execution time is that their host does not allow them to. Make sure to find out that they do not block this.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.