在阅读了大量有关 SQL Server 中临时表和表变量之间差异的信息后,我正在尝试从主要使用临时表切换到主要使用表变量。(它们似乎更适合我通常使用的查询类型。)
在这些查询中,表包含驱动查找过程的唯一标识符。在使用临时表时,我的习惯是包含一个PRIMARY KEY约束,以便查询优化器知道它不会看到任何重复项。但是,鉴于优化器(在大多数情况下,对于我的查询)假定表变量仅包含单行*,根据定义这是唯一的,如果存在PRIMARY KEY约束,查询优化器是否会做出任何不同的选择?
* 从技术上讲,它假定没有行,但将零替换为一。(因为零与估计过程的其余部分的交互非常差。)但这也取决于在编译查询时是否填充了表变量。这里有一些背景信息:SQL Server 中的临时表和表变量有什么区别?.
我目前正在使用 SQL Server 2014,但我很好奇新版本的行为是否发生变化。
正如已经指出的那样,PRIMARY KEY约束带有聚集索引,它为查询优化器提供了更多关于如何从表变量中获取数据的选择。我意识到了这一点,并考虑了查询计划的其余部分。但是在试图澄清我的问题之后,我决定我试图提出的问题太广泛了,可能特别针对我的极端情况。(不过是对半万亿行表的导航类型查询,期望达到亚秒级性能。)所以我将保持我的问题不变。
第一个查询(插入表变量)的时间是第二个查询的两倍。它在执行计划中不使用并行性。
第二个查询(插入临时表)在其执行计划中使用并行性,并且能够在几乎一半的时间内实现结果。
我试图从表函数运行它,因此需要表变量而不是临时表。
执行计划非常复杂,我宁愿不朝那个方向深入(目前)。我想知道是否有人解释或假设为什么第一个 SQL 不使用并行性,而第二个是。
第一的:
DECLARE @TableVar as TABLE (
[Date] [date] NULL,
[B] [int] NULL,
[C] [decimal](5, 3) NULL)
INSERT INTO
@TableVar
SELECT
[Date] = CAST(LO.Dt as Date)
, [B] = DMC.[B]
, [C] = DMC.[C]
FROM
dbo.fnTblFunc1(@DateStart, @DateEnd) AS DMC
INNER JOIN dbo.fnTblFunc2(@DateStart, @DateEnd) AS LO ON DMC.Date = LO.Dt
OPTION (FORCE ORDER )
Run Code Online (Sandbox Code Playgroud)
第二:
CREATE TABLE #TempTbl(
[Date] [date] NULL,
[B] [int] NULL,
[C] [decimal](5, 3) NULL)
INSERT INTO
#TempTbl
SELECT
[Date] = CAST(LO.Dt …Run Code Online (Sandbox Code Playgroud) 我有一些运行缓慢的查询(按月分组的 100 万条记录中的 8 秒),并且一直试图理解执行计划。我们使用大约 10 个 TVP 来发送一组用户选择的过滤器,我有一个索引视图,占查询成本的 84%。
执行计划比较大,不能上传到这里,所以上传到这里了
我花了很多时间来尝试优化这些查询(其中有 14 个,但每个查询的核心都大同小异)并且希望任何人在阅读它们时提出建议或提示。我还实现了实际执行计划建议的查询,但查询速度慢了 5 倍?
performance sql-server execution-plan sql-server-2012 table-valued-parameters query-performance
我有 2 个不同的查询来识别重复(如下)。两个查询之间的唯一区别是一个使用 CTE,另一个使用 #Temp 表。
有谁知道为什么 CTE 比 #Temp 表快得多(0:20 秒 VS. 1:22)?
我宁愿使用 CTE,但我需要使用 CTE 运行 2 个 STATEMENTS(从 CTE 删除,然后从 CTE 插入表),但 SQL Server 只允许您在 CTE 上编写一个 STATEMENT。
查询 1:
WITH DUPS AS(
Id,
Column1,
Column2,
Column3,
RN = ROW_NUMBER()OVER(PARTITION BY ID ORDER BY id)
FROM mytable
)
Select top 1 * FROM DUPS WHERE RN > 1
Run Code Online (Sandbox Code Playgroud)
查询 2:
SELECT
Id,
Column1,
Column2,
Column3,
RN = ROW_NUMBER()OVER(PARTITION BY ID ORDER BY id)
INTO #DUPS
FROM mytable …Run Code Online (Sandbox Code Playgroud) 我正在处理一个基本上将大量表聚合在一起的查询。
我尝试的第一种方法是将所有表内部连接成一个漂亮的大查询,看起来像这样:
select
a.col1
, a.col2
, a.col3
...
, b.col1
...
...
, l.col1
, l.col2
from myprimarytable a
join secondtable b on a.key = b.key
join third table c on a.key = c.key
...
join thelasttable l on a.key = b.key
Run Code Online (Sandbox Code Playgroud)
这需要永远运行。但是,看起来像这样的第二个解决方案:
create table #output (
primkey char(40)
, mycol1 char(1) null
, mycol2 decimal(20,1) null
...
, mylastcol varchar(max) null
)
insert into #output
select
a.col1
, a.col2
...
from myprimarytable a
update #output set
mycol3 = …Run Code Online (Sandbox Code Playgroud)