相关疑难解决方法(0)

表变量有主键时对执行计划的影响

在阅读了大量有关 SQL Server 中临时表和表变量之间差异的信息后,我正在尝试从主要使用临时表切换到主要使用表变量。(它们似乎更适合我通常使用的查询类型。)

在这些查询中,表包含驱动查找过程的唯一标识符。在使用临时表时,我的习惯是包含一个PRIMARY KEY约束,以便查询优化器知道它不会看到任何重复项。但是,鉴于优化器(在大多数情况下,对于我的查询)假定表变量仅包含单行*,根据定义这是唯一的,如果存在PRIMARY KEY约束,查询优化器是否会做出任何不同的选择?

* 从技术上讲,它假定没有行,但将零替换为一。(因为零与估计过程的其余部分的交互非常差。)但这也取决于在编译查询时是否填充了表变量。这里有一些背景信息:SQL Server 中的临时表和表变量有什么区别?.

我目前正在使用 SQL Server 2014,但我很好奇新版本的行为是否发生变化。


正如已经指出的那样,PRIMARY KEY约束带有聚集索引,它为查询优化器提供了更多关于如何从表变量中获取数据的选择。我意识到了这一点,并考虑了查询计划的其余部分。但是在试图澄清我的问题之后,我决定我试图提出的问题太广泛了,可能特别针对我的极端情况。(不过是对半万亿行表的导航类型查询,期望达到亚秒级性能。)所以我将保持我的问题不变。

sql-server optimization table-variable

4
推荐指数
2
解决办法
1308
查看次数

与临时表并行但不是表变量?

第一个查询(插入表变量)的时间是第二个查询的两倍。它在执行计划中不使用并行性。

第二个查询(插入临时表)在其执行计划中使用并行性,并且能够在几乎一半的时间内实现结果。

我试图从表函数运行它,因此需要表变量而不是临时表。

执行计划非常复杂,我宁愿不朝那个方向深入(目前)。我想知道是否有人解释或假设为什么第一个 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)

sql-server parallelism temporary-tables table-variable

3
推荐指数
1
解决办法
1855
查看次数

使用 TVP 了解执行计划

我有一些运行缓慢的查询(按月分组的 100 万条记录中的 8 秒),并且一直试图理解执行计划。我们使用大约 10 个 TVP 来发送一组用户选择的过滤器,我有一个索引视图,占查询成本的 84%。

执行计划比较大,不能上传到这里,所以上传到这里了

我花了很多时间来尝试优化这些查询(其中有 14 个,但每个查询的核心都大同小异)并且希望任何人在阅读它们时提出建议或提示。我还实现了实际执行计划建议的查询,但查询速度慢了 5 倍?

performance sql-server execution-plan sql-server-2012 table-valued-parameters query-performance

2
推荐指数
1
解决办法
315
查看次数

为什么在此查询中使用 CTE 比使用 #Temp 表快得多?

我有 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)

sql-server

2
推荐指数
1
解决办法
6561
查看次数

大规模连接与更新临​​时表

我正在处理一个基本上将大量表聚合在一起的查询。

我尝试的第一种方法是将所有表内部连接成一个漂亮的大查询,看起来像这样:

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)

join sql-server temporary-tables

1
推荐指数
1
解决办法
7112
查看次数