Optimize SUM with time segment WHERE
And why don't you simply create b-tree index on created_at column?
Or compound (created_at+kpi) ? In the second case all the information will be taken during the index scan and no need to read blocks from the table itself.
But if the time range between X and Y is rather big, then the optimizer might think that full table scan is cheaper anyway.
In some particular situations the clustered index may be a good solution, too. For example by days or months, so when you select values, all blocks are read from the same area that belongs to that cluster.