nor*_*tos 8 performance sql-server-2008 sql-server derived-tables temporary-tables query-performance
我读到派生表比临时表具有更好的性能,但无论如何许多 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;
Run Code Online (Sandbox Code Playgroud)
派生表
/*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;
Run Code Online (Sandbox Code Playgroud)
临时表
/*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;
Run Code Online (Sandbox Code Playgroud)
@user16484 已经将您引导至评论中的哪一个具有更好的性能:派生表或临时表。
另请参阅临时表“vs”表变量“vs”CTE。它还包括派生表。
快速总结:#temp 表可以被索引,可以有唯一的索引/约束,可以在同一个查询中被多次引用,可以被多个查询引用(FROM 或 JOIN)。派生表可以在一个查询中被引用(FROM 或 JOIN)一次。
在性能方面,取出 Profiler for SQL:BatchCompleted 和 RPC:Completed,观察 Read、Write、CPU 和 Duration 列,看看派生表、#temp 表和索引 #temp 表的几次运行有何作用每个特定的查询。
一般来说 - 如果您要多次使用它,#temp 表会胜出。如果您要加入很多表,#temp 表可能会胜出。如果您只加入几个表,派生表有合理的获胜机会。基准它!
小智 6
通常,这取决于您的特定查询和临时结果的大小。
对于给定的特定场景,即分页,临时表是完全没有必要的。为什么要将 1000 行保存到临时表中,然后只返回第 200 行?在这种情况下使用“派生”表或 CTE 效率更高,因为完整的结果集不必存储在任何地方,或者在大多数情况下甚至生成。例如,当请求 200 行的第一页时,只需要从基表中检索前 200 行(假设现有索引可以支持查询中请求的排序顺序)。
| 归档时间: |
|
| 查看次数: |
21499 次 |
| 最近记录: |