let me just say again that I really appreciate this, RR!
I have basically done what you described in your last post. I have my initial query which fetches all the records and then I have my own routine to choose the results randomly. i'm using mysql_result() instead of mysql_data_seek(). I'm not really sure what the difference is. it seems to be working.
I must confess, I am running two queries and my first one uses 'SELECT DISTINCT e.id'. I have checked and the 2nd query to fetch the other info typically takes a few milliseconds or less. These don't seem to be the problem though as the first query is what's taking all the time.
I popuplated my tables with some random sample data:
events - 50,000 records
event_time_assoc - 115,607 records
zip_codes - 43,000 records.
I've set up a page that keeps updating the target timestamps with the current time so I can be sure that I'm not getting cached results.
My first query typically runs in 1.5 seconds:
SELECT DISTINCT e.id
FROM demo_events e
INNER JOIN demo_event_time_assoc eta ON e.id=eta.event_id
WHERE e.active =1
AND ((eta.start_timestamp >=1163590783
AND eta.start_timestamp <=1164195583)
OR (eta.start_timestamp <1163590783
AND eta.end_timestamp >=1163594383)) ORDER BY NULL
Your recommendation runs in about 2 seconds each time:
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 >=1163591310
AND eta.start_timestamp >=1164196110)
OR (eta.start_timestamp <1163591310
AND eta.end_timestamp >=1163594910))
Seems to me it's these initial queries that are the problem because they seem to be scanning tables rather than using indexes.
this EXPLAIN statement says as much basically:
EXPLAIN
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 >=1163591310
AND eta.start_timestamp >=1164196110)
OR (eta.start_timestamp <1163591310
AND eta.end_timestamp >=1163594910))
the results:
table type possible_keys key key_len ref rows Extra
eta ALL event_id,start_timestamp,end_timestamp NULL NULL NULL 115607 Using where
e eq_ref PRIMARY PRIMARY 4 eta.event_id 1 Using where
z eq_ref PRIMARY PRIMARY 5 e.zip 1
The table has indexes which appear to be getting ignored for some reason. too many indexes maybe? I was originally using unix-style timestamps and couldn't decide between those and mysql datetime format. You can recreate the eta table with this:
CREATE TABLE `demo_event_time_assoc` (
`id` int(15) unsigned NOT NULL auto_increment,
`event_id` int(11) unsigned NOT NULL default '0',
`start_datetime` datetime NOT NULL default '0000-00-00 00:00:00',
`start_timestamp` int(12) NOT NULL default '0',
`end_datetime` datetime NOT NULL default '0000-00-00 00:00:00',
`end_timestamp` int(12) NOT NULL default '0',
`start_hour` tinyint(3) unsigned NOT NULL default '0',
`end_hour` tinyint(3) unsigned NOT NULL default '0',
PRIMARY KEY (`id`),
KEY `event_id` (`event_id`),
KEY `start_timestamp` (`start_timestamp`),
KEY `end_timestamp` (`end_timestamp`),
KEY `start_datetime` (`start_datetime`),
KEY `end_datetime` (`end_datetime`)
) TYPE=MyISAM AUTO_INCREMENT=115608 ;