If I am getting you correctly you could try this..
SET @tdate = '2012-01-01 00:00:00';
SELECT
b.bug_id
,CASE
WHEN s.removed IS NULL THEN b.bug_status
ELSE s.removed
END AS statusAtDate
,CASE
WHEN o.removed IS NULL THEN b.op_sys
ELSE o.removed
END AS apSysAtDate
FROM
bugs AS b
LEFT OUTER JOIN (
SELECT
a.bug_id
,a.bug_when
,a.removed
,a.bug_when
,@row_num := IF(@last=a.bug_id,@row_num+1,1) AS rnk
,@last:=a.bug_id
FROM
bug_activity AS a
INNER JOIN fielddefs AS f
ON a.fieldid = f.id
AND f.name = 'bug_status'
WHERE
a.bug_when <= @tdate
ORDER BY
a.bug_id
,a.bug_when
) AS s
ON b.bug_id = s.bug_id
AND s.rnk=1
LEFT OUTER JOIN (
SELECT
a.bug_id
,a.bug_when
,a.removed
,a.bug_when
,@row_num := IF(@last=a.bug_id,@row_num+1,1) AS rnk
,@last:=a.bug_id
FROM
bug_activity AS a
INNER JOIN fielddefs AS f
ON a.fieldid = f.id
AND f.name = 'op_sys'
WHERE
a.bug_when <= @tdate
ORDER BY
a.bug_id
,a.bug_when
) AS o
ON b.bug_id = o.bug_id
AND o.rnk=1
--repeat for resolution and rep_platform
sorry I don't have a db here to verify the code so sorry if there is typos or similar..
I don't know if that's how you were doing the left outer join before but does that help/work if you use a session variable for re-use?
not sure if this will be of any assistance at all seeing as you said that your left outer join method was running at the same speed anyway.. maybe mysql query optimiser can figure a better way of doing it without this :/
I am no optimisation expert by the way (far from it).. just saying what i would try other than the good suggestion to get some indexes on the go.
EDIT:
Another thing you could try.. I think this should work..
SELECT
bug_id
,bug_status
,op_sys
,max(old_status)
,max(old_opSys)
(
SELECT
*
FROM
bugs AS b
LEFT OUTER JOIN (
SELECT
a.bug_id
,a.bug_when
,if(f.name = 'bug_status',a.removed,NULL) AS old_status
,if(f.name = 'op_sys',a.removed,NULL) AS old_opSys
,a.bug_when
,@row_num := IF(@last=a.bug_id AND@lastField=f.name ,@row_num+1,1) AS rnk
,@last:=a.bug_id
,@lastField:=f.name
FROM
bug_activity AS a
INNER JOIN fielddefs AS f
ON a.fieldid = f.id
WHERE
a.bug_when <= '2012-01-01 00:00:00'
AND f.name in( 'bug_status','op_sys')
ORDER BY
a.bug_id
,f.name
,a.bug_when
) AS s
ON b.bug_id = s.bug_id
AND s.rnk=1
) AS T
GROUP BY
bug_id
,bug_status
,op_sys
I have left out the case or if statement from the outer select here.. I was thinking no matter which solution it might be worth testing how it runs doing the final checks in code rather than the DB? even if that works you might not opt for it but it might be worth checking.
as in something like:
<%= row->old_status ?: row->bug_status %>
(sorry if my PHP is off.. not really used it much)
seems like it should work? http://sqlfiddle.com/#!2/eff8c/1