如何在T-SQL上的Union子句上获得更好的性能

Mir*_*yev 3 sql t-sql sql-server query-performance

我有三张桌子。每个表包含超过3M行。我运行以下代码:

SELECT * FROM 
(
    SELECT col_1, col_2, col_3, [date], 1 as type FROM table_1
    UNION
    SELECT col_1, col_2, col_3, [date], 2 as type FROM table_2 
    UNION
    SELECT col_1, col_2, col_3, [date], 3 as type FROM table_3
) AS tb 
tb.[date] BETWEEN (start_date) AND (end_date)  
ORDER BY [date] DESC OFFSET n ROWS FETCH NEXT m ROWS ONLY
Run Code Online (Sandbox Code Playgroud)

但是,当我得到较大的日期间隔时,查询运行会变慢。例如:当我得到2019-01-01和2019-04-01间隔时,查询运行约13-14秒:

执行计划

这个结果非常糟糕。我想在1秒内得到结果。我能做什么?

Gor*_*off 5

首先使用UNION ALL而不是UNION

SELECT *
FROM (SELECT col_1, col_2, col_3, [date], 1 as type FROM table_1
      UNION ALL
      SELECT col_1, col_2, col_3, [date], 2 as type FROM table_2 
      UNION ALL
      SELECT col_1, col_2, col_3, [date], 3 as type FROM table_3
     ) AS tb 
WHERE tb.[date] BETWEEN (start_date) AND (end_date)  
ORDER BY [date] DESC
OFFSET n ROWS FETCH NEXT m ROWS ONLY;
Run Code Online (Sandbox Code Playgroud)

SQL使用删除重复项会产生开销UNIONUNION ALL不会产生此开销。

另外,date在每个表中的索引应有所帮助。SQL Server具有良好的优化程序,通常可以将此类条件下推至UNION/ UNION ALL子查询中的各个查询。