标签: sql-server-2019

什么时候应该在索引上使用 IGNORE_DUP_KEY 选项?

有人说最好制作您的查询以避免重复的键异常,但我不相信仅设置IGNORE_DUP_KEY = ON索引的性能更高。

我的目标是在尝试更新这些行之前,确保为一个或多个用户存在一行或一组行。我这样做,所以当我尝试使用如下所示的更新语句更新行时,没有行受到影响,这是因为[Count]谓词的部分不满足,而不是根本不存在的行(即[ID]不满足谓词的部分):

UPDATE [Inventory]
SET [Count] = [Count] + 1
WHERE [ID] = 3 
AND ([Count] + 1) <= @MaxInventory
Run Code Online (Sandbox Code Playgroud)

我可以运行EXISTS(SELECT 1 From [Inventory] WHERE [ID] = 3检查该单行,如果该行不存在,则仅插入该行。这只是避免了不必要的插入。如有必要,插入仍需处理并发事务,因此仍可能发生重复键异常。

我很好奇IGNORE_DUP_KEY在这种情况下是否只打开性能更好,而不是允许抛出和捕获错误。具体来说,我很好奇它是否与运行存在检查一样快或什至可能更快,只是尝试插入记录并让它忽略重复的键。

当我一次检查和初始化多个记录时,这变得更加重要。例如,如果我需要确保单个更新语句中存在数千个用户的记录,如果我只是预先运行该插入语句,让它忽略重复的键,那么逻辑会简单得多。避免重复会更复杂,因为我必须首先查询不存在记录的表,然后尝试仅添加这些记录(再次忽略重复键)。即使所有记录都存在,只是插入可能会更快。

我可以在中途遇到它并检查是否有任何记录丢失,例如使用左连接或COUNT比较,但是如果忽略重复键的插入速度更快,为什么还要麻烦呢?

使用IGNORE_DUP_KEY并尝试插入而不是提前检查行是否存在是个好主意吗?如果不是,为什么?

sql-server duplication unique-constraint sql-server-2019

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

SQL重启后,CTE在SQL Server 2019中短时间内导致无效对象名称错误

我们在 SQL Server 2016 数据库中有一些已经投入生产一段时间的 SQL 代码;但在重新启动 SQL Server 后的第一个小时左右(从 5-10 分钟到一个小时或更长时间,可能取决于 SQL Server 中的活动级别),它会在 SQL Server 2019 数据库中引发错误。错误是 CTE(公用表表达式)的“对象名称无效”。

我们在 SQL Server 2016 中有一个包含多个数据库的生产环境。我们现在已经使用 SQL Server 2019(在 Windows Server 2016 机器上,具有 24GB 的 RAM 和 4 个 CPU 内核)设置了一个新的开发/测试环境,以便我们可以进行测试使用 SQL Server 2019。此测试服务器上的数据库是从生产备份中恢复的生产数据库副本。测试环境中的所有数据库的兼容级别都设置为 150(SQL Server 2019)。

每天清晨,我们开始看到一些使用 CTE 的函数存在一些问题,这些函数会引发如下错误:

SqlException (0x80131904): Invalid object name 'CTEuniqueName'.]

Msg 208, Level 16, State 1, Procedure ufn_FunctionName, Line 28 [Batch Start Line 0]
Invalid object name 'CTEuniqueName'.
Run Code Online (Sandbox Code Playgroud)

错误在短时间内停止发生,直到第二天早上才再次发生。

错误发生在一对一个接一个调用的存储过程中,它们都调用了相同的(用户定义的 SQL)函数。通过一些测试,我了解到有时只需调用该函数,然后仅从该函数执行一段代码,就可能导致相同的错误。

我还发现,通过重新启动 SQL Server 实例并调用函数或代码块,我可能会持续导致错误。这可能也是它只在清晨失败的原因 …

sql-server cte functions sql-server-2019

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

执行alter table的数据文件和日志文件的巨大磁盘空间

我的 SQL Server 数据库上的文件大小有一个大问题。

让我把一切都放在上下文中:

在一个空数据库上,我正在创建一个新表:

CREATE TABLE mytable
(
    id int identity(1,1) NOT NULL, 
    description varchar(255) NOT NULL
);
Run Code Online (Sandbox Code Playgroud)

=> 在磁盘上,我有 datafile=8192K 和 logfile=8192k

我将 1'000'000 行插入到我的表中,如下所示:

INSERT INTO mytable(description)
    SELECT TOP (1000000) 
        'test test test test test test test test test test test'
    FROM sys.all_objects AS o1
    CROSS JOIN sys.all_objects AS o2
    CROSS JOIN sys.all_objects AS o3;
Run Code Online (Sandbox Code Playgroud)

=> 在磁盘上,我有 datafile=73M 和 logfile=376M

我正在更改描述列,将其数据类型更改为nvarchar

ALTER TABLE mytable 
    ALTER COLUMN description nvarchar(255) NOT NULL;
Run Code Online (Sandbox Code Playgroud)

=> 在磁盘上,我有 datafile=204M 和 …

sql-server sql-server-2019

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

Intellisense 自动禁用“WITH Inline = OFF”?

在我的 SSMS(我使用的是 18.10)项目中,我对 Intellisense 在我的文件中不起作用这一事实感到沮丧。我猜测这是由于代码库的大小造成的,但事实上,我发现有点奇怪。

在下面的代码中:

CREATE FUNCTION X() RETURNS INT
WITH INLINE = OFF
AS
BEGIN
RETURN 1;
END;
Run Code Online (Sandbox Code Playgroud)

如果我删除WITH INLINE = OFF,Intellisense 会重新打开。到底是怎么回事?

sql-server ssms sql-server-2019

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

查询存储的总体资源消耗报告是否告诉我我的数据库运行得很糟糕,或者这些数字只是被破坏了?

最近,我们将一台生产服务器从 SQL Server 2016 升级到 SQL Server 2019 (CU 15)。这对我来说是一个在我们的主应用程序数据库上启用查询存储的绝佳机会。它已经运行了几天,这是总体资源消耗报告显示的内容:

总体资源消耗报告

在屏幕截图中,我精心挑选了一些看起来很疯狂的数字(查询存储启用的第一天),并将它们标准化为更容易讨论的度量单位。诸如逻辑读取消耗约 183 TB的数据,或内存消耗约 5 TB的数据之类的事情,在这台服务器上似乎几乎是不可能的。

该数据库是数据库中的 John Smith,数据文件大小仅为100 GB ,日志文件大小为200 GB 。全天最多可能有 100 个不同的用户连接到它,并且一天内不会创建大量交易。服务器本身仅为其配置了32 GB内存。要消耗5 TB内存,一天中分配的内存需要被填满150 多次。

我可以考虑添加的唯一其他可能相关的信息是升级后,我们立即将此数据库的“兼容性级别”设置为 150 (SQL Server 2019) 并保留“旧基数估计”设置。我知道这并不理想,最好在收集基线指标时让尘埃落定,但升级的部分原因是为了解决一些紧急的性能问题,从我们的测试来看,这些设置组合实际上最有效(并且仍然看起来)工作得很好)。

我们之前遇到的一些性能问题是由于疯狂的基数估计造成的,如果查询存储使用估计数据点,那么我实际上可以看到此报告的数字是相关的,但我不得不想象该报告是使用实际数据点?不过,如果这是我的生产服务器/数据库在我不断征服基数估计问题时的配置方式存在根本错误的另一个迹象,那将会很有趣。

我是否读错了这些数字,查询存储是否出问题了,或者我的服务器是否正常?

performance sql-server upgrade query-store sql-server-2019

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

Polybase 的性能

我们一直在 SQL Server 2019 (CU2) 机器上试验 Polybase,使用 SQL Server 外部数据源,但性能并不好 - 在大多数情况下提高了 1400%。在每种情况下,我们查询的所有表/视图都来自指向同一外部数据源的外部表。我们尝试过运行在本地框上分解的查询,并使用与作为外部表拉入的视图相同的查询。我们还将来自远程服务器的每个统计数据脚本化到外部表上,没有任何变化。您可以使用示例查询在下面看到性能差异。

服务器在资源方面设置相同:32GB 的 RAM、8 个 vCPU、SSD 磁盘,并且没有其他正在运行的查询。我尝试过两台不同的远程服务器,一台运行带有最新 SP/CU 的 SQL Server 2016,另一台运行 CU2 的单独 2019 机器。服务器是在同一台主机上运行的虚拟机,我们已经排除了任何类型的主机争用。

示例查询:

SELECT
     StockItem_StockNumber, BlanktypeId, NameHTML, BackgroundStrainName, IsExact, IsConditional
     ,ROW_NUMBER() Over(Partition By StockItem_StockNumber, BlanktypeId Order By pt.Name, p.Name, gptr.Text) as row_num
     ,pt.Name as Level1, p.Name as Level2, gptr.Text as Level3, MGIReference_JNumber
     ,gptr.Type as Level3Type  
FROM
     StockItemBlanktypes sig
     INNER JOIN Blanktypes g on g.BlanktypeId = sig.Blanktype_BlanktypeId
     INNER JOIN BlanktypeStockTerms gpt on gpt.Blanktype_BlanktypeId = g.BlanktypeId …
Run Code Online (Sandbox Code Playgroud)

sql-server polybase sql-server-2019

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

SQL Server 2019 大 INSERT 的性能问题

我们正在将多个 ETL 过程从 SQL Server 2016、Windows 2012 服务器转换为 Windows 2019、SQL Server 2019 (CU8) 环境。

一个进程在 SQL Server 2019 中的运行时间比在 SQL Server 2016 中的运行时间长。该进程执行一个INSERT into B, select x from A, wherex是一系列子字符串和 case 语句。

表 A 基本上包含 1 个数据列,6,000 字节长。表 B 由 950 多个数据列组成。我将平面文件中的数据批量插入到表 A 中,然后使用各种子字符串命令将数据解析到表 B 中。

表 A 包含 470 万行并在 47 分钟内加载,为了测试目的我拆分了 100 万行,并在 10 分钟内加载。

在我的 SQL Server 2016、Windows 2012 服务器上,满载运行时间为 12 - 14 分钟,而 100 万次采样运行时间为 1 分 51 秒。

为了咧嘴笑,我在我的 ETL 2019 …

sql-server sql-server-2019

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

SQL Server 2019 服务在启动时意外终止但手动启动

在过去的几个月里,我的 SQL Server 2019 服务器运行良好,但自上周五以来它开始自行停止。今天早上,我在上面安装了最新的累积更新。

这是我的版本

Microsoft SQL Server 2019 (RTM-CU8-GDR) (KB4583459) - 15.0.4083.2 (X64) 2020 年 11 月 2 日 18:35:09 版权所有 (C) 2019 Microsoft Corporation Developer Edition(64 位),Windows Server 2019 Standard 10.0(内部版本 17763:)(管理程序)

我也遇到了 SQL Server 2019 标准版 (RTM-CU8-GDR) 的问题。

每次都会创建一个小型转储。分析转储后,我可以看到内核基础异常。

内核异常

这台服务器只运行 SQL Server,我没有在机器上运行更多的东西。

在 SQL 的日志文件中,我看到在此消息之后进行了转储。

错误日志

在 Windows 事件查看器中,我只有一条错误消息,指出 SQL 正在停止。

事件查看器

就在那个错误之前,我有关于 SQLException64 的树“Windows 错误报告”错误。

事件查看器错误报告

重新启动 SQL Server 不会改变任何东西。但是,如果我打开 SQL 管理控制台并启动 SQL 服务,它就可以正常启动。

我真的不知道在哪里检查,如何进一步诊断。

这是迷你转储文件。

2021-01-18 10:15:18.56 spid58      ex_terminator: Possible termination due to exception during stack unwinding. …
Run Code Online (Sandbox Code Playgroud)

sql-server sql-server-2019

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

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
查看次数

假设SQL Server有巨大的内存来容纳整个数据库,那么索引有什么好处呢?

据我所知,索引查找允许服务器通过查找索引快速转到所需的页面,因此无需将查询表的所有页面从磁盘读取到内存中即可获得好处。

这个问题假设:

  1. 整个数据库有巨大的内存存储在内存中,
  2. 被查询的表没有索引,
  3. 查询是从表中选择数据,其中说rate>100
  4. 带有上述 WHERE 子句的第一个查询将进行扫描,将整个表的数据页从磁盘拉入内存(因为 上没有索引rate)。

在这种情况下,我的问题是,对于使用相同 WHERE 子句 ( rate>50) 对该表进行的后续查询,SQL 引擎将对已驻留在内存中的页面执行表扫描。rate当整个表位于内存中并且不需要访问磁盘时,列上是否有索引对第二个查询有任何好处吗?

index sql-server sql-server-2019

6
推荐指数
2
解决办法
2063
查看次数