Cash desk reporting was exported synchronously: forty-odd seconds of waiting and a timeout on longer periods. We moved the export into a background job with a progress indicator, and the reading onto a cursor with constant memory use. Along the way we learned to show the number of pages without recounting the whole table and to jump to the last page in seconds.
The export became a background job with a readiness indicator: the user no longer keeps a tab open and no longer hits a timeout on a long period.
Reading runs on a keyset cursor with constant memory use — the size of the selection no longer affects consumption. The number of pages is estimated without recounting the whole table, to within about 0.1%, and jumping to the end of the list takes seconds instead of tens of minutes.
The match between what is on the screen and what ends up in the file is fixed by an automated test: they can no longer drift apart unnoticed.