相关疑难解决方法(0)

CTE 和临时表有什么区别?

通用表表达式 (CTE) 和临时表有什么区别?我什么时候应该使用一个?

CTE

WITH cte (Column1, Column2, Column3)
AS
(
    SELECT Column1, Column2, Column3
    FROM SomeTable
)

SELECT * FROM cte
Run Code Online (Sandbox Code Playgroud)

临时表

SELECT Column1, Column2, Column3
INTO #tmpTable
FROM SomeTable

SELECT * FROM #tmpTable
Run Code Online (Sandbox Code Playgroud)

sql-server cte

183
推荐指数
7
解决办法
19万
查看次数

为什么在这种特定情况下使用表变量的速度是 #temp 表的两倍多?

我正在查看此处的文章 Temporary Tables vs. Table Variables and their Effect on SQL Server Performance and on SQL Server 2008 能够重现与 2005 中显示的结果类似的结果。

当执行只有 10 行的存储过程(定义如下)时,表变量 version out 执行临时表 version 的两倍以上。

我清除了过程缓存并运行了两个存储过程 10,000 次,然后再重复该过程 4 次。结果如下(每批时间以毫秒为单位)

T2_Time     V2_Time
----------- -----------
8578        2718      
6641        2781    
6469        2813   
6766        2797
6156        2719
Run Code Online (Sandbox Code Playgroud)

我的问题是:表变量版本性能更好的原因什么?

我做了一些调查。例如查看性能计数器

SELECT cntr_value
from sys.dm_os_performance_counters
where counter_name = 'Temp Tables Creation Rate';
Run Code Online (Sandbox Code Playgroud)

确认在这两种情况下,临时对象都按预期在第一次运行后被缓存,而不是每次调用都从头开始创建。

类似地跟踪Profiler 中的Auto Stats, SP:Recompile,SQL:StmtRecompile事件(下面的屏幕截图)显示这些事件仅发生一次(在第一次调用#temp表存储过程时),其他 9,999 次执行不会引发任何这些事件。(表变量版本没有得到任何这些事件) …

sql-server temporary-tables

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

为什么表变量强制索引扫描而临时表使用查找和书签查找?

我试图理解为什么使用表变量会阻止优化器使用索引查找然后书签查找与索引扫描。

填充表:

CREATE TABLE dbo.Test 
(
    RowKey INT NOT NULL PRIMARY KEY, 
    SecondColumn CHAR(1) NOT NULL DEFAULT 'x',
    ForeignKey INT NOT NULL 
) 

INSERT dbo.Test 
(
    RowKey, 
    ForeignKey
) 
SELECT TOP 1000000 
    ROW_NUMBER() OVER (ORDER BY (SELECT 0)),
    ABS(CHECKSUM(NEWID()) % 10)     
FROM sys.all_objects s1
CROSS JOIN sys.all_objects s2 

CREATE INDEX ix_Test_1 ON dbo.Test (ForeignKey) 
Run Code Online (Sandbox Code Playgroud)

使用单个记录填充表变量,并尝试通过搜索外键列来查找主键和第二列:

DECLARE @Keys TABLE (RowKey INT NOT NULL) 

INSERT @Keys (RowKey) VALUES (10)

SELECT 
    t.RowKey,
    t.SecondColumn
FROM
    dbo.Test t 
INNER JOIN 
    @Keys k
ON
    t.ForeignKey = …
Run Code Online (Sandbox Code Playgroud)

sql-server optimization sql-server-2008-r2 user-defined-table-type bookmark-lookup

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

在不返回任何行的查询中包含 ORDER BY 会严重影响性能

给定一个简单的三表连接,当包含 ORDER BY 时,即使没有返回行,查询性能也会发生巨大变化。实际问题场景需要 30 秒才能返回零行,但在不包括 ORDER BY 时是即时的。为什么?

SELECT * 
FROM tinytable t                          /* one narrow row */
JOIN smalltable s on t.id=s.tinyId        /* one narrow row */
JOIN bigtable b on b.smallGuidId=s.GuidId /* a million narrow rows */
WHERE t.foreignId=3                       /* doesn't match */
ORDER BY b.CreatedUtc          /* try with and without this ORDER BY */
Run Code Online (Sandbox Code Playgroud)

我知道我可以在 bigtable.smallGuidId 上建立索引,但是,我相信在这种情况下这实际上会使情况变得更糟。

这是创建/填充表以进行测试的脚本。奇怪的是,smalltable 有一个 nvarchar(max) 字段似乎很重要。我使用 guid 加入 bigtable 似乎也很重要(我猜这使它想要使用哈希匹配)。

CREATE TABLE tinytable
  (
     id        INT PRIMARY KEY IDENTITY(1, 1),
     foreignId …
Run Code Online (Sandbox Code Playgroud)

performance sql-server

16
推荐指数
2
解决办法
3582
查看次数

@table_variable 或 #temp_table

我有一个大的用户定义的表类型变量,它有 129 列。我将一次在这个表变量中存储大约 2000-3000 条记录,并将其传递给各种存储过程和函数以获取附加数据并进行修改。然后,这些附加数据和新修改将存储在相同类型的新表变量中,并通过OUTPUT参数返回到源存储过程。(这是因为表类型参数只能作为READONLY.)

这是我的伪代码:

  SP1
  @tmp tableType
  {
        INSERT @tmp EXEC
        SP2 (@tmp)

        INSERT @tmp EXEC
        SP3 (@tmp)
  }
Run Code Online (Sandbox Code Playgroud)

我应该使用 a@table_variable还是#temp_table

performance sql-server-2008 sql-server

12
推荐指数
2
解决办法
555
查看次数

Dodgy T-SQL 查询执行让我发疯

执行计划SQL Server 2019。这是 xml 计划要点的链接。

您好,我花了很长时间才明白为什么当它找不到包含其中一种状态的记录时,为什么这个查询需要 0.02 秒才能执行。当它找到具有包含状态之一的记录时,它往往要快得多。我猜这是因为一旦找到匹配的 1 行,查询就会停止。

SELECT TOP 1 IDNum,
             FORMAT(Date, 'M/d/yy') AS theDate,
             Status,
             Rate
FROM   theDB
       INNER JOIN DomainTable
               ON theDB.IDNum = DomainTable.IDNum
WHERE  DomainIP = '127.0.0.1'
       AND status IN ( 'Active', 'To ReActivate', 'To Deactivate', 'Deactivate ASAP',
                       'SUSPENDED', 'SUSPENDED X', 'SUSPENDED Y', 'SUSPENDED Z' )
ORDER  BY theDB.IDNum DESC 
Run Code Online (Sandbox Code Playgroud)

(DomainIP属于DomainTable,其他属于DB)

在执行计划中,最大的成本是 TOP N SORT,占 33% 聚集索引搜索占 29% 对 DomainTable 的键查找使用了 29% 在 DomainTable 上搜索 IP 的索引是 9%

我的问题是:

有没有办法让TOP N不那么重?

0.02 …

sql-server t-sql sql-server-2019

11
推荐指数
2
解决办法
3352
查看次数

在 IF EXISTS 查询中使用 CTE

是否可以在 SQL Server 2012 中执行类似于以下操作?

IF EXISTS (
    WITH DATA AS (
        SELECT *, 
        ROW_NUMBER() OVER(PARTITION BY column ORDER BY Column) AS rn
        FROM table )
    SELECT *
    FROM DATA
    WHERE rn = 2 )
BEGIN
...
END
Run Code Online (Sandbox Code Playgroud)

我尝试使用此语法并收到错误消息。如果这是不可能的,使用临时表是实现此目的的最佳方法吗?

sql-server cte

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

生成差异的最有效方法

我在 SQL Server 中有一个表,如下所示:

Id    |Version  |Name    |date    |fieldA   |fieldB ..|fieldZ
1     |1        |Foo     |20120101|23       |       ..|25334123
2     |2        |Foo     |20120101|23       |NULL   ..|NULL
3     |2        |Bar     |20120303|24       |123......|NULL
4     |2        |Bee     |20120303|34       |-34......|NULL
Run Code Online (Sandbox Code Playgroud)

我正在研究一个存储过程来区分,它需要输入数据和版本号。输入数据包含从 Name up 到 fieldZ 的列。大多数字段列预计为NULL,即每行通常只有前几个字段的数据,其余为NULL。名称、日期和版本构成了表上的唯一约束。

对于给定的版本,我需要对输入的与该表相关的数据进行比较。每一行都需要区分——一行由名称、日期和版本标识,字段列中任何值的任何更改都需要显示在差异中。

更新:所有字段都不需要是十进制类型。其中一些可能是 nvarchars。我更希望 diff 发生而不转换类型,尽管 diff 输出可以将所有内容转换为 nvarchar,因为它仅用于显示目的。

假设输入如下,请求的版本为2,:

Name    |date    |fieldA   |fieldB|..|fieldZ
Foo     |20120101|25       |NULL  |.. |NULL
Foo     |20120102|26       |27    |.. |NULL
Bar     |20120303|24       |126   |.. |NULL
Baz     |20120101|15       |NULL  |.. |NULL
Run Code Online (Sandbox Code Playgroud)

差异需要采用以下格式:

name    |date    |field    |oldValue    |newValue
Foo     |20120101|FieldA …
Run Code Online (Sandbox Code Playgroud)

join sql-server union cross-apply

8
推荐指数
2
解决办法
224
查看次数

MSSQL 表变量识别

有什么方法可以识别哪个存储过程在 tempDB 中创建表变量?

我正在查看 sys.dm_db_index_operational_stats 中的 forward_fetch_count,我们有几个表的计数非常大(最大的超过 1.33 亿)。表名以 # 后跟 8 个十六进制字符的形式出现在 tempDB 中。有没有办法将其追溯到原始流程,以便我们修复它?

我们在 Linux 上运行 SQL 2019。

谢谢,埃文

sql-server sql-server-2019

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

varchar 和 nvarchar 在调整存储过程中 - 如何提高这种情况下的性能?

我有以下过程,每天调用超过一百万次,我认为可以对其进行调整以更好地使用资源。

ALTER PROCEDURE [DenormV2].[udpProductTaxRateGet]
(
    @itemNo varchar ( 20 ),
    @calculateDate datetime,
    @addressLine1 nvarchar( 50 ),
    @addressLine2 nvarchar( 50 ),
    @addressLine3 nvarchar( 50 ),
    @addressLine4 nvarchar( 50 ),
    @addressLine5 nvarchar( 50 ),
    @addressLine6 nvarchar( 50 ),
    @postalCode nvarchar( 20 ),
    @countryCode varchar( 2 ),
    @addressFormatID int
)
WITH EXECUTE AS 'webUserWithRW'
AS
--see Bocss2.dbo.[fnGetProductTax] for equivalent logic and comments in Bocss
DECLARE @Addresses TABLE (TaxRegionId int NOT NULL)

INSERT INTO @Addresses(TaxRegionId)
SELECT  DISTINCT TaxRegionId
FROM    dbo.[ShipTaxAddress]
WHERE   [CountryCode] = @countryCode …
Run Code Online (Sandbox Code Playgroud)

performance sql-server-2005 sql-server execution-plan table-variable query-performance

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