How to efficiently store impressions in db?
Summary tables.  Separate table for counts.
Are you keeping information about each impression?  Or just a counter?  It makes a big difference.  But we can solve it either way.
If you go with a table with just daily counter:
CREATE TABLE FooImpressions (
    foo_id  INT UNSIGNED NOT NULL,  -- same as main table, but not AUTO_INCREMENT
    date DATE NOT NULL,
    counter INT UNSIGNED NOT NULL,
    PRIMARY KEY(foo_id, date)
) ENGINE=InnoDB;

And
INSERT INTO FooImpressions (foo_id, date, counter)
    VALUES (?, ?, 1)
    ON DUPLICATE KEY UPDATE
        counter = VALUES(counter) + 1;

This automatically starts a new row for each Foo each day (as needed).
Then, to get last weeks counts:
SELECT foo_id, SUM(counter) AS impressions
    FROM FooImpressions
    WHERE date &gt;= CURDATE() - INTERVAL 7 DAY
      AND date  &lt; CURDATE()
    GROUP BY foo_id;

Of course, the date range can be changed to handle any consecutive date range.
There are variants on this for more complex situations and for situations that need more performance.  But this is a simple &quot;summary table&quot; together with its maintenance and its usage.
Yes, one variation would have DATETIME and truncate that to the hour.  Don't have both an hourly summary table and a daily one until you have demonstrated that the hourly one is not fast enough.
If you need up-to-the-minute counts, some Summary techniques do not provide such (because the do nightly or hourly batch updates for speed); the use of IODKU is always up-to-the-minute.
Even if you have another table with more info on the impressions, have this Summary table for speed of reporting.
More discussion:  http://localhost/rjweb/mysql/doc.php/summarytables