No idea which is line 336; but since the given code only has 105 (probably the last 105) there may be something using up big chunks of memory elsewhere. Not the size of the tables themselves so much or what's being done with them in the query (managing that memory is MySQL's responsibility), but if there's a huge result set returned that's still sitting around after it has been finished with (without being unset()), then it will continue to sit around and take up space.
Starting at the beginning, I can see one opportunity for improvement:
$query="SELECT a.book, a.rarity, a.price, a.sid FROM collector_books a LEFT JOIN collector_books_read b ON a.sid = b.sid and b.uid = $user->uid WHERE b.sid IS NULL";
$result=mysql_query($query);
$num=mysql_numrows($result);
$i=0;
while ($i < $num) {
$sid=mysql_result($result,$i,"sid");
if($_REQUEST[$sid] == "on")
mysql_query("INSERT INTO collector_books_read VALUES ($sid, $user->uid)");
$i++;
}
Since only 'sid' is ever used:
$query="SELECT a.sid FROM collector_books a LEFT JOIN collector_books_read b ON a.sid = b.sid and b.uid = $user->uid WHERE b.sid IS NULL";
$result=mysql_query($query);
$num=mysql_numrows($result);
for($i=0; $i<$num; $i++) {
$sid=mysql_result($result,$i,"sid");
if($_REQUEST[$sid] == "on")
mysql_query("INSERT INTO collector_books_read VALUES ($sid, $user->uid)");
}
The code for determining the value of $order_by could be streamlined:
if($_REQUEST['Submit'] != true){
if($_REQUEST['order_by']==""){
$order_by="book";
$_SESSION['old_page']=$order_by;
}
elseif(in_array($_REQUEST['order_by'], array('book','rarity','price'))) {
$order_by = $_REQUEST['order_by'];
if($_SESSION['old_page']==$order_by)
$order_by .= " desc";
$_SESSION['old_page'] = $order_by;
}
}else
$order_by = $_SESSION['old_page'];
(Incidentally, you'll be better off using isset() to determine whether or not $_REQUEST['Submit'] is set.)
But that's not going to do much for memory usage.
I don't know if it would improve matters (I'm kind of suspecting not), but using mysql_fetch_array() is a more efficient method of pulling successive rows from a database result set than extracting each individual field one at a time from each row:
for($i=0; $i<$num; $i+=2) {
list($book,$rarity,$price,$sid) = mysql_fetch_array($result);
$checkbox="<input type='checkbox' name='$sid'>";
echo "<tr>";
echo "<td>$book</td><td><div style='text-align:right;'>$rarity</div></td><td><div style='text-align:right;'>$price</div></td><td><div style='text-align:right;'>$checkbox</div></td>";
if(($i+1) != $num){ // slightly faster - $i+1 is always < $num unless it == $num
list($book2,$rarity2,$price2,$sid2) = mysql_fetch_array($result);
$checkbox2="<input type='checkbox' name='$sid2'>";
echo "<td>$book2</td><td><div style='text-align:right;'>$rarity2</div></td><td><div style='text-align:right;'>$price2</div></td><td><div style='text-align:right;'>$checkbox2</div></td>";
}
else
echo "<td></td><td></td><td></td><td></td>";
echo "</tr>";
}
The start and end of the form don't need to be in PHP as there is no processing
involved:
$result=mysql_query($query);
$num=mysql_numrows($result);
mysql_close();
?>
<center><b>Book Collector Checklist - Not Read</b><br><a href='#bottom'>Jump to bottom</a><br><br><a href='?q=bookchecklist_read'>Books Read</a> | Books Not Read<br></center>";
<form name="form1" method="post" action="">
<table align='center' border=1 cellpadding=4 cellspacing=0>
<tr><td><b><a href='?q=bookchecklist_notread&order_by=book'>Book</a></b></td><td><b><center><a href='?q=bookchecklist_notread&order_by=rarity'>Rarity</a></center></b></td><td><b><center><a href='?q=bookchecklist_notread&order_by=price'>Price</a></center></b></td><td><b><center>Read</center></b></td><td><b><a href='?q=bookchecklist_notread&order_by=book'>Book</a></b></td><td><b><center><a href='?q=bookchecklist_notread&order_by=rarity'>Rarity</a></center></b></td><td><b><center><a href='?q=bookchecklist_notread&order_by=price'>Price</a></center></b></td><td><b><center>Read</center></b></td></tr>
<?php
(And you do know that <center> has been deprecated in favour of using the text-align style? You could probably replace
<td><b><center><a href='?q=bookchecklist_notread&order_by=rarity'>Rarity</a></center></b></td>
with
<th><a href='?q=bookchecklist_notread&order_by=rarity'>Rarity</a></th>
and get what you're after even without having to specify additional styles for <th> elements in the stylesheet.)
But aside from that first thing, I don't see any major memory hogs (unless this is a Really Big Table being output!)