@Valex has the right solution, which is an index on the date
field.
I want to comment that a table of 300 millions rows, and growing, is a large table. This query suggests that recent data is more important than older data. If so, you should be learning about partitioning.
Partitioning is a way of splitting a large table into smaller storage units. If a query only needs to access one of them, then only that data is read for processing -- a big savings. For instance, if your data were partitioned by month and you had 36 months of data, then your query would only have to access 2 months worth. This would be a savings of almost 95% over reading all the data.
Here is the MySQL documentation on partitioning.