Questions tagged «sql-server-2017»

SQL Server 2017(主要版本14.00.xxxx)。还请标记sql-server。

5
将许多可空整数1:1转换为二进制字符串的最快方法是什么?
我的部分工作量使用CLR函数,该函数实现了怪异的哈希算法来比较行以查看是否有任何列值已更改。CLR函数将二进制字符串作为输入,因此我需要一种快速的方法将行转换为二进制字符串。我希望在整个工作负载中散列大约100亿行,因此我希望这段代码尽可能快。 我有大约300个具有不同架构的表。出于这个问题的目的,请假设一个简单的表结构包含32个可为空的INT列。在此问题的底部,我提供了示例数据以及一种基准测试结果的方法。 如果所有列值都相同,则行必须转换为相同的二进制字符串。如果任何列值不同,则行必须转换为不同的二进制字符串。例如,以下简单的代码将不起作用: CAST(COL1 AS BINARY(4)) + CAST(COL2 AS BINARY(4)) + .. 它不能正确处理NULL。如果COL1第1行为COL2NULL,第2行为NULL,则两行都将转换为NULL字符串。我相信正确处理NULL是正确转换整个行的最难的部分。INT列的所有允许值都是可能的。 要优先考虑一些问题: 如果这很重要,那么在大多数情况下(90%+),列将不会为NULL。 我必须使用CLR。 我必须对这么多行进行哈希处理。我无法保留这些哈希值。 我相信由于CLR功能的存在,我无法使用批处理模式进行转换。 将32个可INT为空的列转换为BINARY(X)或VARBINARY(X)字符串的最快方法是什么? 样本数据和代码如下: -- create sample data DROP TABLE IF EXISTS dbo.TABLE_OF_32_INTS; CREATE TABLE dbo.TABLE_OF_32_INTS ( COL1 INT NULL, COL2 INT NULL, COL3 INT NULL, COL4 INT NULL, COL5 INT NULL, COL6 INT …

1
无法在非唯一索引上插入重复的键行?
在连续八周无错误之后,过去几天我们三度遇到了这个奇怪的错误,我很沮丧。 这是错误消息: Executing the query "EXEC dbo.MergeTransactions" failed with the following error: "Cannot insert duplicate key row in object 'sales.Transactions' with unique index 'NCI_Transactions_ClientID_TransactionDate'. The duplicate key value is (1001, 2018-12-14 19:16:29.00, 304050920).". 我们拥有的索引不是唯一的。如果您注意到,错误消息中的重复键值甚至不会与索引对齐。奇怪的是,如果我重新运行proc,它将成功。 这是我发现的最新链接,但有我的问题,但没有解决方案。 https://www.sqlservercentral.com/forums/topic/error-cannot-insert-duplicate-key-row-in-a-non-unique-index 关于我的场景的几件事: proc正在更新TransactionID(主键的一部分)-我认为这是导致错误的原因,但不知道为什么?我们将删除该逻辑。 在表上启用了更改跟踪 进行事务读取未提交 每个表有45个字段,我主要列出索引中使用的字段。我在更新语句中(不必要)更新TransactionID(集群键)。奇怪的是,直到上周,我们几个月都没有遇到任何问题。而且这只是通过SSIS偶尔发生的。 表 USE [DB] GO /****** Object: Table [sales].[Transactions] Script …


1
为什么此RX-X锁没有出现在扩展事件中?
问题 我有一对可串行隔离的查询,它们导致RX-X锁定。但是,当我使用扩展事件来观察锁获取时,RX-X锁获取从未出现,它仅被释放。它从何而来? 再现 这是我的桌子: CREATE TABLE dbo.LockTest ( ID int identity, Junk char(4) ) CREATE CLUSTERED INDEX CX_LockTest --not unique! ON dbo.LockTest(ID) --preload some rows INSERT dbo.LockTest VALUES ('data'),('data'),('data') 这是我的问题批次: SET TRANSACTION ISOLATION LEVEL SERIALIZABLE BEGIN TRAN INSERT dbo.LockTest VALUES ('bleh') SELECT * FROM dbo.LockTest WHERE ID = SCOPE_IDENTITY() --ROLLBACK …

1
仅物理checkdb失败,但完整的一个成功完成
我正在执行带有physical_only选项的checkdb,并且失败,并显示以下多个错误: 消息8965,级别16,状态1,第1行 表错误:对象ID 1557580587,索引ID 1,分区ID 72057594088456192,分配单元ID 72057594177454080(类型为行内数据)。页面(1:13282192),插槽3,文本ID 6370769698816的行外数据节点由页面(0:0),插槽0引用,但未在扫描中看到。消息8965,级别16,状态1,第1行 表错误:对象ID 1557580587,索引ID 1,分区ID 72057594088456192,分配单元ID 72057594177454080(类型为行内数据)。页面(1:13282192)插槽5的行外数据节点由页面(0:0)插槽0引用文本ID 6370769764352,但在扫描中未看到。 CHECKDB在表'TableX'(对象ID 1557580587)中发现了0个分配错误和5255个一致性错误。CHECKDB在数据库'DatabaseX'中发现0个分配错误和5255个一致性错误。repair_allow_data_loss是DBCC CHECKDB(DWH_LAND)发现的错误的最低修复级别。 但是完整的checkdb是成功的: CHECKDB在数据库'DatabaseX'中发现0个分配错误和0个一致性错误。DBCC执行完成。如果DBCC打印了错误消息,请与系统管理员联系。 TableX大约有20万行,并在其上具有群集的列存储索引。 我们正在使用以下版本的SQL Server: Microsoft SQL Server 2017(RTM-CU13)(KB4466404)-14.0.3048.4 我应该担心吗?


1
SQL 2017 TDE数据库中的备份压缩导致损坏
在SQL Server 2017(CU3)上,每当我在一个TDE数据库上启用备份压缩时,备份过程始终会损坏数据库中的特定页面。如果我运行备份时不进行压缩,则不会损坏它。这是我为验证和重现此问题而采取的步骤: 在数据库“ TDE_DB1”上运行DBCC CheckDB;一切都很好,没有错误; 成功备份数据库而无需压缩;RESTORE VERIFYONLY表示一切都很好; 成功将数据库还原为“ TDE_DB2”;一切都很好,DBCC CheckDB没有显示任何错误; 使用压缩成功备份“ TDE_DB1”数据库;RESTORE VERIFYONLY错误,提示“检测到备份集损坏”; 尝试将数据库还原为“ TDE_DB2”;错误,说“ RESTORE在数据库中的页面(1:92454)上检测到错误” 重复步骤1-3;一切都很好; DROP“ TDE_DB1”和“ TDE_DB2”; 从备份中还原“ TDE_DB1”;一切都很好; 重复步骤1-5;得到相同的结果 总结一下:数据库和常规备份看起来不错,在数据库上运行CHECKDB并在备份上运行VERIFYONLY不会报告任何错误。使用压缩备份数据库似乎会导致损坏。 下面是有错误的代码示例。(注意:将压缩与TDE数据库一起使用需要MAXTRANSFERSIZE) -- Good, completes with no corruption; BACKUP DATABASE [TDE_DB1] TO DISK = N'E:\MSSQL\Backup\TDE_DB1a.bak' WITH CHECKSUM; RESTORE VERIFYONLY FROM DISK = N'E:\MSSQL\Backup\TDE_DB1a.bak' WITH CHECKSUM; RESTORE …

1
启动SQL Server 2017服务时出错。错误代码3417
我的计算机上安装了SQL Server 2017。这是SELECT @@VERSION返回的内容: Microsoft SQL Server 2017(RTM-GDR)(KB4293803)-14.0.2002.14(X64)2018年7月21日版权所有(C)2017 Windows 10 Enterprise 10.0(内部版本17134)上的Microsoft Corporation Enterprise Edition(64位): )` 到昨天为止,一切都很好。突然SQL SERVER Service没跑。当我想手动运行该服务时,显示3417 error。当我检查事件日志时,看到此错误: 数据库'master'的脚本级别升级失败,因为升级步骤'msdb110_upgrade.sql'遇到错误200,状态7,严重性25。这是一个严重的错误情况,可能会干扰常规操作,并且数据库将脱机。如果错误是在“ master”数据库升级期间发生的,它将阻止整个SQL Server实例启动。检查以前的错误日志条目中是否有错误,采取适当的纠正措施,然后重新启动数据库,以便脚本升级步骤运行完成。 经过一番谷歌搜索后,我发现可以使用它/T902 switch并尝试解决问题。但是没有解决方案对我有用。因此,我安装了另一个相同实例SQL SERVER 2017并还原了数据库。现在,新安装的实例具有相同的问题。 可能是什么问题呢? 更新 这是SQL Server的完整错误日志。 2018-09-17 13:06:47.29 spid6s配置选项“显示高级选项”从1更改为1。运行RECONFIGURE语句进行安装。 2018-09-17 13:06:47.29 spid6s配置选项“显示高级选项”从1更改为1。运行RECONFIGURE语句进行安装。 2018-09-17 13:06:47.29 spid6s配置选项'Agent XPs'从1更改为1。运行RECONFIGURE语句进行安装。 2018-09-17 13:06:47.29 spid6s配置选项'Agent XPs'从1更改为1。运行RECONFIGURE语句进行安装。 2018-09-17 13:06:47.29 spid6s创建SSIS文件夹... 2018-09-17 13:06:47.30 …

4
将NVARCHAR(4000)列快速更改为NVARCHAR(260)
我在使用非常大的内存授予时遇到了一个性能问题,需要处理两NVARCHAR(4000)列该表。问题是这些列永远不会大于NVARCHAR(260)。 使用 ALTER TABLE [table] ALTER COLUMN [col] NVARCHAR(260) NULL 导致SQL Server重写整个表(并在日志空间中使用2倍的表大小),这是数十亿行,只能更改任何内容,这是不可行的。增大列宽不会出现此问题,但是减小它确实会出现此问题。 我尝试创建约束,CHECK (DATALENGTH([col]) <= 520)或者CHECK (LEN([col]) <= 260)SQL Server仍然决定重新编写整个表。 有什么方法可以将列数据类型更改为仅元数据操作?无需重写整个表?我正在使用SQL Server 2017(14.0.2027.2和14.0.3192.2)。 这是用于重现的示例DDL表: CREATE TABLE [table]( id INT IDENTITY(1,1) NOT NULL, [col] NVARCHAR(4000) NULL, CONSTRAINT [PK_test] PRIMARY KEY CLUSTERED (id ASC) ); 然后运行ALTER。

3
将大表上的更改列速度提高到NON NULL
我最近在一个表中添加了一个可为NULL的位列,该表具有近5亿行。列上没有默认值,但是所有插入都将值指定为0或1,并且我运行了一次例程,将0或1分配给所有现有行(小批量更新行)。现在,每一行在该列中应具有0或1。 我想使bit列不可为空,但是当我尝试通过via进行操作时ALTER TABLE t1 ALTER COLUMN c1 bit not null,它开始运行了3分钟,并且我停止了它,因为它阻止了对表的所有读取,并且我怀疑它将花费很长时间才能完成。可能不会花费太长时间,但是我不能冒太多不可用的风险。回滚本身花费了6分钟。 您对我如何使该列不可为空而不可能花费数小时才能完成有什么建议? 另外,有什么方法可以估算ALTER TABLE ALTER COLUMN我开始然后取消的语句需要多长时间? 我正在使用SQL Server 2017 Web Edition。

3
IndexOptimize之后查询和更新非常慢
数据库SQL Server 2017 Enterprise CU16 14.0.3076.1 最近,我们尝试从默认的“索引重建”维护作业切换到Ola Hallengren IndexOptimize。默认的索引重建作业已经运行了几个月,没有任何问题,并且查询和更新在可接受的执行时间内正常工作。在IndexOptimize数据库上运行后: EXECUTE dbo.IndexOptimize @Databases = 'USER_DATABASES', @FragmentationLow = NULL, @FragmentationMedium = 'INDEX_REORGANIZE,INDEX_REBUILD_ONLINE,INDEX_REBUILD_OFFLINE', @FragmentationHigh = 'INDEX_REBUILD_ONLINE,INDEX_REBUILD_OFFLINE', @FragmentationLevel1 = 5, @FragmentationLevel2 = 30, @UpdateStatistics = 'ALL', @OnlyModifiedStatistics = 'Y' 性能极度下降。使用100ms之前的一条更新语句IndexOptimize之后(使用相同的计划)花费了78.000ms,并且查询的执行情况也差了几个数量级。 由于这仍然是一个测试数据库(我们正在从Oracle迁移生产系统),因此我们恢复为备份并禁用IndexOptimize,一切恢复正常。 但是,我们想了解与可能导致这种极端性能下降IndexOptimize的“正常” Index Rebuild行为有何不同,以确保一旦投入生产就可以避免这种情况。关于寻找什么的任何建议将不胜感激。 update语句执行速度慢时的执行计划。即 在IndexOptimize 实际执行计划之后(尽快推出) 我还没发现差异。 快速计划相同的查询 实际执行计划

1
为什么需要汇总此流?
查看此查询。这非常简单(有关表和索引的定义以及repro脚本,请参见文章结尾): SELECT MAX(Revision) FROM dbo.TheOneders WHERE Id = 1 AND 1 = (SELECT 1); 注意:“ AND 1 =(SELECT 1)只是为了防止此查询被自动参数化,我觉得这使问题感到困惑-尽管有或没有该子句,它实际上都得到相同的计划 这是计划(粘贴计划链接): 由于那里有一个“ top 1”,我很惊讶地看到流聚合运算符。对我来说似乎没有必要,因为保证只有一行。 为了检验该理论,我尝试了这个逻辑上等效的查询: SELECT MAX(Revision) FROM dbo.TheOneders WHERE Id = 1 GROUP BY Id; 这是该计划(粘贴计划链接): 果然,按计划分组无需流聚合运算符就可以通过。 请注意,两个查询均从索引末尾读取“向后”,并执行“ top 1”以获取最大修订。 我在这里想念什么? 流聚合实际上是在第一个查询中进行工作,还是应该将其消除(这不是优化器的限制,而并非如此)? 顺便说一句,我意识到这不是一个非常实际的问题(两个查询都报告了0 ms的CPU和经过的时间),我只是好奇这里展示的内部/行为。 这是我在运行上述两个查询之前运行的设置代码: DROP TABLE IF EXISTS dbo.TheOneders; …


2
为什么DELETE查询以一种格式运行的时间要长于另一种格式?
我有特定的清理代码,试图删除一些重复项。 它可以在许多客户站点上完美运行。日志告诉我,此查询至少消耗1秒到45秒: DELETE FROM [tbl] WHERE [Id] NOT IN ( SELECT MIN([Id]) FROM [tbl] GROUP BY [IdProject], [IdRepresentative], [TimeStart] ) 但是我有一个客户,该查询运行了4个多小时(到现在为止还没有结束)!我检查了数据库(DBCC CHECKDB),我已经更新了统计信息(sp_updatestats),也UPDATE STATISTICS [tbl] WITH FULLSCAN没有显示任何更改。 我有客户的数据库原始备份。我在SQL Server 14.0.2002.14上运行它。我有标准版,客户使用Express Edition。 我可以在活动监视器中看到没有其他人正在使用该数据库。无需等待,CPU使用率达到25%(恰好是我4个CPU中的1个)。同样在这个测试用例中,没有其他人正在使用数据库。 我重新设计了查询并检查了以下语句: DELETE FROM [tbl] FROM [tbl] AS t LEFT OUTER JOIN ( SELECT MIN([Id]) AS [IdMin] FROM [tbl] GROUP …

2
为什么我将Int / Smallint隐式转换为Varchar,这真的会影响基数估计吗?
我正在尝试使用实际执行计划上的“显示计划分析”(SSMS)来执行性能缓慢的查询。分析工具指出,行数的估计值与计划中某些位置的返回结果不符,并进一步给了我一些隐式转换警告。 我不理解这些从int到Varchar的隐式转换-引用的字段不是查询中任何参数/过滤器的一部分,并且在涉及的所有表中,列数据类型都是相同的: 我收到以下CardinalityEstimate警告: 表达式中的类型转换(CONVERT_IMPLICIT(varchar(12),[ccd]。[profileid],0))可能会影响查询计划选择中的“ CardinalityEstimate”-该字段在我的数据库中到处都是整数 表达式中的类型转换(CONVERT_IMPLICIT(varchar(6),[ccd]。[nodeid],0))可能会影响查询计划选择中的“ CardinalityEstimate”-该字段在我数据库中的每个地方都是smallint 表达式中的类型转换(CONVERT_IMPLICIT(varchar(6),[ccd]。[sessionseqnum],0))可能会影响查询计划选择中的“ CardinalityEstimate”-该字段在我的数据库中到处都是smallint 表达式中的类型转换(CONVERT_IMPLICIT(varchar(41),[ccd]。[sessionid],0))可能会影响查询计划选择中的“ CardinalityEstimate”-该字段在我的数据库中到处都是小数 [编辑]这是查询和实际执行计划,以供参考 https://www.brentozar.com/pastetheplan/?id=SysYt0NzN 和表定义 /****** Object: Table [dbo].[agentconnectiondetail] Script Date: 1/10/2019 9:10:04 AM ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[agentconnectiondetail]( [sessionid] [decimal](18, 0) NOT NULL, [sessionseqnum] [smallint] NOT NULL, [nodeid] [smallint] NOT NULL, [profileid] [int] …

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.