mas*_*ani 23 sql t-sql sql-server performance
有时我们可以使用派生表和临时表编写查询.我的问题是哪一个更好?为什么?
Qua*_*noi 21
派生表是一种逻辑结构.
它可以存储在tempdb运行时,通过每次访问时重新评估基础语句,甚至根本不进行优化.
临时表是物理构造.它是一个tempdb创建并使用值填充的表.
哪一个更好取决于它们使用的查询,用于派生表的语句以及许多其他因素.
例如,每次使用时都会(并且很可能会)重新评估CTE(公共表表达式)SQL Server.这个查询:
WITH q (uuid) AS
(
SELECT NEWID()
)
SELECT *
FROM q
UNION ALL
SELECT *
FROM q
Run Code Online (Sandbox Code Playgroud)
将最有可能产生两种不同NEWID()的.
在这种情况下,应使用临时表,因为它保证其值保持不变.
另一方面,这个查询:
SELECT *
FROM (
SELECT *, ROW_NUMBER() OVER (ORDER BY id) AS rn
FROM master
) q
WHERE rn BETWEEN 80 AND 100
Run Code Online (Sandbox Code Playgroud)
使用派生表更好,因为使用临时表将需要从中获取所有值master,而此解决方案将仅100使用索引扫描第一个记录id.
onu*_*ade 10
这取决于具体情况.
派生表的优点:
派生表是较大的单个查询的一部分,并将在查询的其余部分的上下文中进行优化.如果查询优化有助于提高性能(通常情况下,除了一些例外情况),这可能是一个优势.示例:如果您填充临时表,然后在第二个查询中使用结果,您实际上将数据库引擎绑定到一个执行方法(完整地运行第一个查询,保存整个结果,运行第二个查询)使用派生表,优化器可能能够找到更快的执行方法或访问路径.
派生表仅在查询执行计划方面"存在" - 它纯粹是一个逻辑构造.真的没有桌子.
临时表的优点
表"存在" - 也就是说,它实现为一个表,至少在内存中,它包含结果集并且可以重用.
在某些情况下,当您必须对数据执行一些精细的转换时,可以提高性能或减少阻塞 - 例如,如果要从繁忙的基表中获取"快照"行集,然后执行对该集合进行一些复杂的计算,如果从基表中获取行并尽快解锁,则可以减少争用,然后独立完成工作.在某些情况下,相对于并发的优势,实际临时表的开销很小.
我想在这里添加一个轶事,因为它引导我对接受的答案提出相反的建议.我同意接受的答案中提出的想法,但它主要是理论上的.我的经验使我建议临时表而不是派生表,公用表表达式和表值函数.在我们开始处理更大的结果集和/或更复杂的查询之前,我们广泛使用派生表和公用表表达式,并基于与已接受答案一致的思想取得了很大成功.然后我们发现优化器没有很好地优化派生表或CTE.
我看了今天跑到10:15的一个例子.我将派生表中的结果插入临时表,并在主查询中加入临时表,总时间下降到0:03.通常当我们看到一个重大的性能问题时,我们可以通过这种方式快速解决 出于这个原因,我建议使用临时表,除非您的查询相对简单,并且您确定它不会处理大型数据集.
| 归档时间: |
|
| 查看次数: |
24243 次 |
| 最近记录: |