Sorry I've not replied sooner - I've spent the last few days finding out how much I've forgotten in the year since I did any php/html/css. Worst part is I've lost all my base-code so I'm starting from scratch.
Anyway, I'm really not up on EXPLAIN output since I never needed to use it myself: I've been doing relational databases since the '80s - which is why I mostly answer posts in the db forum.
My solution to your problem goes like this:
- Run a query that selects ALL the data in one go, y that I mean all the candidates AND all the columns you want as well. Do not impose any grouping, distinct, ordering, randomisation, or anything else that will slow the query down. Keep your WHERE conditions to those that are required.
Do not worry about duplication of events since we are going to deal with that in code.
This should return a large resultset in only fractions of a second.
2, Now process the results in code to select and display 10 random events with no duplicates. Now there is code for a function that does this in the RAND() manual, but it is based on fetching all the rows first, which is a lot of unnecessary processing. I'm sure that my solution could be converted into a function that you just pass the resultset reference to.
$sql = "SELECT e.id, e.title, e.subheading, e.zip, eta.start_timestamp, eta.end_timestamp, z.city, z.st
FROM demo_events e INNER JOIN demo_event_time_assoc eta ON e.id=eta.event_id INNER JOIN demo_zip_codes z ON e.zip=z.zip
WHERE e.active =1 AND
((eta.start_timestamp >=1162506800 AND eta.start_timestamp >=1163111600)
OR
(eta.start_timestamp <1162506800 AND eta.end_timestamp >=1162510400))";
$result=mysql_query($sql) or die();
// get limit for rand()
$up = mysql_num_rows($result);
// set up count
$c = 10;
// set up array to hold event ids and enable ellimination of duplicates
$ary = array();
while (count($ary ) < $c) {
// get random number for index - remember result index is zero-based so we minus 1
$i = rand(1, $up) - 1;
// move pointer to that row number and fetch the data
mysql_data_seek($result, $i);
$row = mysql_fetch_array($result);
// check if the event id has already been displayed
if (!in_array($row['eventid'], $ary)) {
// display the event data
echo '<tr><td>' . $row['eventid'] . 'etc, etc';
// store the id to prevent duplication
array_push($ary, $row['eventid']);
}
}
Now, you may need to change the query if it is not getting the right fields - but don't be tempted to add any conditions. The selection of random events takes care of any events with duplicate listings because it has to take care of the possibility that rand() will return the same number - which everyone forgets that it can.
This approach should be fastest no matter how many records you are dealing with.
Hope this helps.