与SQL Server中的派生表相比,使用临时表是否有优势?


8

我读到派生表比临时表具有更好的性能,但是无论如何,许多SQL Server开发人员都喜欢第二个表。为什么?我必须对大数据(数百万条记录)进行查询,并且我想确保使用的是最佳选择。

CREATE TABLE A(
    id BIGINT IDENTITY(1,1) NOT NULL,
    field1 INT NOT NULL,
    field2 VARCHAR(50) NULL,
);

CREATE TABLE B(
    id INT IDENTITY(1,1) NOT NULL,
    field1 VARCHAR(10) NULL,
    field2 INT NULL
);

INSERT INTO A 
    (field1,field2)
VALUES 
    (1,'a'),(2,'b'),(3,'c'),(2,'d'),(5,'e'),
    (6,'f'),(7,'g'),(8,'h'),(9,'i'),(2,'j');

INSERT INTO B 
    (field1,field2)
VALUES 
    ('a',1),('b',2),('c',3),('d',4),('e',5),
    ('f',6),('g',7),('h',8),('i',9),('j',2),('k',3);

DECLARE @begin INT=0,@end INT=200;

派生表

/*derived tables*/
SELECT 
    C.id,C.field1,C.field2,C.field3 
FROM
(
    SELECT
        A.id,A.field1,A.field2,B.field2 AS field3, 
        ROW_NUMBER() OVER (ORDER BY A.id) AS iRow
    FROM 
        A INNER JOIN B ON A.field1=B.id
) C
WHERE iRow BETWEEN @begin AND @end;

临时表

/*temporary tables*/
CREATE TABLE #C (
    iRow INT IDENTITY(1,1),
    id bigint,
    field1 INT,
    field2 VARCHAR(50),
    field3 INT );

INSERT INTO #C 
    (id,field1,field2,field3)
SELECT TOP 1000 
    A.id,A.field1,A.field2,B.field2 
FROM  
    A INNER JOIN B ON A.field1=B.id
ORDER BY 
    A.id;

SELECT id,field1,field2,field3 
FROM #C 
WHERE iRow BETWEEN @begin AND @end;

DROP TABLE #C;

1
你有一个SELECT TOP 1000没有任何东西ORDER BY,那不是很好。我认为您需要添加ORDER BY A.id;两个方法才能等效。
ypercubeᵀᴹ

这只是一个示例。目的是展示我的问题的主要主题。
norgematos 2014年

Answers:


6

@ user16484已将您定向到性能更好的一个:注释中的派生表或临时表

另请参见临时表“ vs”表变量“ vs” CTE。它也涵盖派生表。

快速总结:#temp表可以被索引,可以具有UNIQUE索引/约束,可以在同一查询中多次引用,可以被多个查询引用(FROM或JOIN)。可以一次查询一次引用派生表(FROM或JOIN)。

在性能方面,为SQL:BatchCompleted和RPC:Completed拔出Profiler,观察“读取”,“写入”,“ CPU”和“持续时间”列,并查看派生表与#temp表与索引式#temp表的对应关系每个特定的查询。

通常,如果要多次使用它,则#temp表将获胜。如果要加入很多表,则#temp表可能会获胜。如果您只加入几张桌子,则派生桌子有一定的获胜机会。进行基准测试!


6

通常,它取决于您的特定查询和临时结果的大小。

对于给定的特定情况(即分页),临时表完全没有必要。为什么要只将1000行保存到临时表中然后返回第1行200?在这种情况下,使用“派生”表或CTE效率更高,因为完整的结果集不必存储在任何地方,甚至在大多数情况下甚至不需要生成。例如,当请求200行的第一页时,仅必须从基表中检索前200行(假定现有索引可以支持查询中请求的排序顺序)。


1
+1,尽管我要补充一点,使用派生表还可以使查询优化器同时处理两个查询。这可能是好事,有时甚至是坏事,再次“取决于特定查询”。这就是为什么同时对这两者进行测试(对真实数据而不是样本数据)而不是进行猜测总是好的的原因:-)。
所罗门·鲁兹基2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.