Anyone know how I can optimise this query? It works but it takes so long that it causes server timeouts when there's a heavy load.
$screenRestrict="clientID='1' AND screenID='1'";
$lastupdate="1318515710";
INSERT INTO allvisits (clientID, screenID, hitID, entryPageID, entryPageName, xentryTime, xexitTime, pagecount, minsonsite)(
SELECT
clientID, screenID, id AS hitID, pageID AS entryPageID,
(SELECT name FROM pages WHERE id=entryPageID) AS entryPageName,
(SELECT clicktime FROM clicks WHERE id = hitID AND isFirstClick=1 ) AS xentryTime,
(SELECT MIN(clicktime) FROM clicks WHERE $screenRestrict AND isLastClick=1 AND clicktime > xentryTime) AS xexitTime,
(SELECT COUNT(*) FROM clicks WHERE $screenRestrict AND clicktime BETWEEN xentryTime AND xexitTime) AS pagecount,
(SELECT (xexitTime-xentryTime)/60) AS minsonsite
FROM clicks WHERE $screenRestrict AND isFirstClick=1 AND clicktime>'$lastupdate'
)
Thanks a lot :)
Update:
Thanks to all for the tips. I've added an index to isLastClick and managed to speed it up a good deal but it still takes +10 seconds on a low server load. I've identified the last bottleneck and marked it below. Is there any better way to select the first "isLastClick" record that is later than xentrytime?
SELECT clientid,
screenid,
id AS hitid,
pageid AS entrypageid,
clicktime AS xentrytime,
(SELECT name
FROM pages
WHERE id = entrypageid) AS entrypagename,
(SELECT clicktime
FROM clicks
WHERE clicktime > xentrytime //<<removing this cuts 8.5 seconds!!
AND screenid = '2'
AND islastclick = 1
LIMIT 1) AS xexittime,
(SELECT COUNT(1)
FROM clicks
WHERE screenid = '2'
AND clicktime BETWEEN xentrytime AND xexittime) AS pagecount,
(SELECT ( xexittime - xentrytime ) / 60) AS minsonsite
FROM clicks
WHERE screenid = '2'
AND isfirstclick = 1
AND clicktime > '1318961057'