强制假脱机避免创建临时表?

u23*_*534 2 sql-server-2008 sql-server

我有以下查询,它连接几个非常大的表的透视数据,并且运行速度非常慢。我尝试为每次旋转创建临时表,它运行得更快。这是一种在不创建临时表的情况下强制索引/表假脱机的方法吗?

select ...
from T1 ....
left join (select ... from (select ... from T2....) pivot (sum(C1) on C2 in (...))) p1 
    on ...
left join (select ... from (select ... from T3....) pivot (sum(...) on ... in (...))) p2
    on ...
left join (select ... from (select ... from T4....) pivot (sum(...) on ... in (...))) p3
    on ...
Run Code Online (Sandbox Code Playgroud)

小智 5

StackOverflow上提出并回答了一个非常类似的问题:如何强制子查询与 #temp 表一样执行? 总而言之,

  1. 最可靠的方法就是使用#temp表格并自己具体化。
  2. 如果失败,请参阅提供提示以强制 CTE 或派生表的中间实现。使用TOP(large_number) ... ORDER BY通常可以鼓励结果被假脱机而不是重复地重新评估。即使这有效,但也没有关于线轴的统计数据。
  3. 另一种选择是使用用户定义的函数。多语句函数(如如何在存储过程之间共享数据中所述)似乎强制 SQL Server 具体化子查询的结果。此外,它们允许您在结果表上指定主键和索引以帮助查询优化器。然后可以在 select 语句中使用该函数作为视图的一部分。例如:
CREATE FUNCTION SalesByStore (@storeid varchar(30))
   RETURNS @t TABLE (title varchar(80) NOT NULL PRIMARY KEY,
                     qty   smallint    NOT NULL)  AS
BEGIN
   INSERT @t (title, qty)
      SELECT t.title, s.qty
      FROM   sales s
      JOIN   titles t ON t.title_id = s.title_id
      WHERE  s.stor_id = @storeid
   RETURN
END

CREATE VIEW SalesData As
SELECT * FROM SalesByStore('6380')
Run Code Online (Sandbox Code Playgroud)