Я бы предложил создать индекс покрытия для каждой таблицы, подобный:
CREATE INDEX ix1 ON table_1 (date) INCLUDE (column1, column2, column3)
Это должно помочь с предложением WHERE. Кроме того, SQL Server не придется прикасаться к таблицам, поскольку вся необходимая информация присутствует в индексе.
Вот еще один удар по этому. Предполагая, что OFFSET n ROWS FETCH NEXT m ROWS ONLY
соответствует очень небольшому проценту строк между начальной и конечной датой, напишите запрос, такой как:
WITH cte1 AS (
-- find the first date after n + m window
SELECT date
FROM (
SELECT date FROM table_1 UNION ALL
SELECT date FROM table_2 UNION ALL
SELECT date FROM table_3
) AS x
WHERE date BETWEEN '2019-01-01' AND '2019-04-01'
ORDER BY date DESC OFFSET (n + m) ROWS FETCH NEXT 1 ROW ONLY
), cte2 AS (
SELECT date, column_1, column_2, column_3, 1 AS type FROM table_1 UNION ALL
SELECT date, column_1, column_2, column_3, 1 AS type FROM table_2 UNION ALL
SELECT date, column_1, column_2, column_3, 1 AS type FROM table_3
)
SELECT *
FROM cte2
WHERE date <= '2019-04-01' AND date > (SELECT date FROM cte1)
ORDER BY date DESC OFFSET n ROWS FETCH NEXT m ROWS ONLY