Drop a global variable (temporarily!) in your script somewhere. Call it $debug or something.
At the top of your script define two variables, $start_time and $current_time. Then do
$debug .= "start: $start_time ";
At various points in your script, append $debug with $current_time. This will define what's taking longest.
Supplement this with get_memory_usage() [us3.php.net], adding the values from it to your $debug.
As you do this, you can use explain [dev.mysql.com] on your selects (also explain syntax [dev.mysql.com],) add these to the $debug variable.
At the end of the script,
echo '<!-- ' . $debug . ' -->';
And view source.
Most likely it's not mysql, it's probably an excessive select or loop in your program hanging it up.