I expect your query would perform better if you rewrote it as a JOIN:
SELECT a.ProductID, a.AdditionalInfo, a.OrderDateTime
FROM ProductOrders a
INNER JOIN
( SELECT b.ProductID, MAX(b.OrderDateTime) AS OrderDateTime
FROM ProductOrders b
WHERE b.OrderDateTime < 40544.5
AND b.OrderDateTime > 40539.5
GROUP BY b.ProductID
) b
ON a.ProductID = b.ProductID
AND a.OrderDateTime = b.OrderDateTime;
With a correlated subquery the subquery is reevaluated for every record in ProductOrders
(this is why you are seeing a full table scan), whereas with the JOIN version the subquery is evaluated only once, and the result is reused as necessary.
In this case, because your outer query is very wide (the whole table) and your subquery is much narrower (filtered by date), the join method will be better, if your outer query was very narrow (i.e only expected to return a few rows), then the correlated subquery version would be better as it not beneficial to perform the subquery for all values when only a few results are needed.