Questions tagged «sql-server»

所有版本的Microsoft SQL Server(非MySQL)。还请添加特定于版本的标记,例如sql-server-2016,因为它通常与问题相关。

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
SQL扩展事件会话,用于死锁检测
有没有办法增加<inputbuf>死锁扩展事件会话捕获的死锁XML中元素的大小? 我们希望看到完整的查询,以帮助在应用程序代码中查明问题。 似乎仅限于1024个字符+/-。可以增加吗? 请参阅下面的XML示例。您可以看到<inputbuf>元素的查询文本在选择列表的中间被截断了: <deadlock> <victim-list> <victimProcess id="processc9c0829848" /> </victim-list> <process-list> <process id="processc9c0829848" taskpriority="0" logused="0" waitresource="PAGE: 5:1:40600276 " waittime="696" ownerId="255115931225" transactionname="SELECT" lasttranstarted="2019-04-24T09:29:25.950" XDES="0xc8dfa8da40" lockMode="S" schedulerid="13" kpid="8480" status="suspended" spid="245" sbid="2" ecid="0" priority="0" trancount="0" lastbatchstarted="2019-04-24T09:29:25.950" lastbatchcompleted="2019-04-24T09:29:25.950" lastattention="1900-01-01T00:00:00.950" clientapp="EntityFramework" hostname="MSR-PRD-BDB02" hostpid="43440" loginname="IUSR_BuildDB" isolationlevel="read committed (2)" xactid="255115931225" currentdb="5" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056"> <executionStack> <frame procname="adhoc" …

1
这是服务器过载的症状吗?
我一直在尝试诊断应用程序中的运行缓慢。为此,我记录了SQL Server 扩展事件。 对于这个问题,我正在研究一个特定的存储过程。 但是有一组核心的存储过程,这些存储过程同样可以用作“一对一调查” 而且每当我手动运行其中一个存储过程时,它总是运行很快 如果用户再次尝试:它将运行很快。 存储过程的执行时间千差万别。此存储过程的许多执行都在<1s内返回: 而对于“快速”存储桶,它远小于1s。实际上大约是90毫秒: 但是有很多用户需要等待2s,3s,4s秒。有些必须等待12s,13s,14s。然后就是真正的可怜人,他们必须等待22、23、24秒。 30秒后,客户端应用程序放弃,中止查询,用户不得不等待30秒。 相关查找因果关系 所以我尝试关联: 持续时间与逻辑读取 持续时间与物理读取 持续时间与CPU时间 而且似乎没有任何关联。似乎没有原因 持续时间与逻辑读取:不管是逻辑读取还是多次读取,持续时间仍在剧烈波动: 持续时间与物理读取:即使查询不是从缓存中进行的,并且需要大量物理读取,它也不会影响持续时间: duration vs cpu time:查询所用的CPU时间为0s,还是CPU的完整时间为2.5s,则持续时间具有相同的可变性: 奖励:我注意到持续时间v物理读取和持续时间v CPU时间看起来非常相似。如果我尝试将CPU时间与“物理读取”相关联,就证明了这一点: 原来很多I / O占用了CPU。谁知道! 因此,如果执行查询的行为没有什么可以解释执行时间的差异,这是否暗示它与CPU或硬盘驱动器无关? 如果CPU或硬盘驱动器是瓶颈;难道不是瓶颈吗? 如果我们假设是CPU是瓶颈,那么,该服务器的CPU电源不足: 那么执行使用更多CPU时间的时间不会更长吗? 因为他们必须使用过载的CPU与他人一起完成? 对于硬盘驱动器类似。如果我们假设硬盘驱动器是瓶颈;硬盘驱动器对此服务器没有足够的随机吞吐量: 那么执行更多物理读取操作不会花费更长的时间吗? 因为他们必须使用过载的硬盘I / O与其他人一起完成? 存储过程本身既不执行也不要求任何写操作。 通常它返回0行(90%)。 有时它将返回1行(7%)。 很少会返回2行(1.4%)。 在最坏的情况下,它已返回2行以上(一次返回12行) 因此,这并不像在返回疯狂的数据量。 服务器CPU使用率 服务器的处理器使用率平均约为1.8%,偶尔会激增至18%-因此看来CPU负载似乎不是问题: 因此,服务器CPU似乎没有过载。 但是服务器是虚拟的... 宇宙之外的东西? 我能想象的唯一剩下的就是服务器领域之外的东西。 …

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; …

3
为什么要使用master创建数据库?
我有一个简短的问题,为什么要使用我use master;来创建数据库?这是Microsoft文档中的示例 USE master ; GO CREATE DATABASE Sales ON ( NAME = Sales_dat, FILENAME = 'C:\Program Files\...\saledat.mdf', SIZE = 10, MAXSIZE = 50, FILEGROWTH = 5 ) LOG ON ( NAME = Sales_log, FILENAME = 'C:\Program Files\...\salelog.ldf', SIZE = 5MB, MAXSIZE = 25MB, FILEGROWTH = 5MB ) ;

3
查询挑战:根据度量而非行数创建均匀大小的存储桶
我将以尽可能均匀地向固定数量的卡车装载订单来描述问题。 输入: @TruckCount - the number of empty trucks to fill 一套: OrderId, OrderDetailId, OrderDetailSize, TruckId (initially null) Orders由一个或多个组成OrderDetails。 这里的挑战是TruckId为每个记录分配一个。 一个订单不能跨卡车分割。 卡车应尽可能均匀地*装载,以表示sum(OrderDetailSize)。 *平均:最小载重卡车和最大载重卡车之间可实现的最小增量。根据此定义,1,2,3比1,1,4更均匀地分布。如果有帮助,请假装您是统计算法,甚至可以创建高度直方图。 没有考虑最大卡车负载。这些是魔术弹力卡车。但是卡车的数量是固定的。 有一个明显的解决方案是迭代-循环分配订单。 但是可以按照基于集合的逻辑来完成吗? 我的主要兴趣是针对SQL Server 2014或更高版本。但是针对其他平台的基于集合的解决方案也可能很有趣。 这感觉就像Itzik Ben-Gan的领土:) 我的实际应用程序将处理工作负载分配到多个存储桶中,以匹配逻辑CPU的数量。因此,每个存储桶没有最大大小。统计信息具体更新。我只是认为将问题抽象到卡车上作为解决挑战的一种方式会更有趣。 CREATE TABLE #OrderDetail ( OrderId int NOT NULL, OrderDetailId int NOT NULL PRIMARY KEY, OrderDetailSize tinyint NOT NULL, …

1
如何从SQL Server审核数据中筛选出标量值用户定义的函数用法?
我们有一个SQL Server数据库,该数据库具有数据库审核规范,该规范审核数据库上所有执行的操作。 CREATE DATABASE AUDIT SPECIFICATION [dbAudit] FOR SERVER AUDIT [servAudit] ADD (EXECUTE ON DATABASE::[DatabaseName] BY [public]) 我们发现,某些查询将对结果集中的每一行使用标量函数写入审核日志。当发生这种情况时,在将日志ETL放入最终的静止位置之前,日志已填满,并且日志记录中存在空白。 不幸的是,由于合规性原因,我们不能简单地停止审核每条EXECUTE声明。 解决此问题的方法首先想到的是使用WHERE“ 服务器审核”上的子句来过滤活动。代码如下所示: WHERE [object_id] not in (Select object_id from sys.objects where type = 'FN' ) 不幸的是,SQL Server不允许使用关系IN运算符(可能是因为它不想在每次必须写入审核日志时都进行查询)。 我们想避免编写一个存储过程,其硬代码object_id中WHERE条款,但是这是我们在解决这个问题的最好办法目前的想法。我们是否应该考虑替代方法? 我们注意到,当在递归CTE中使用标量函数时,它将导致查询将查询写入结果集中的每一行。 供应商提供了一些标量值函数,我们无法删除或移动到备用数据库。

3
模拟用户定义的标量函数,其方式不会阻止并行性
我正在尝试查看是否存在一种诱使SQL Server对查询使用特定计划的方法。 1.环境 假设您有一些在不同进程之间共享的数据。因此,假设我们有一些实验结果需要很多空间。然后,对于每个过程,我们都知道要使用哪个年/月的实验结果。 if object_id('dbo.SharedData') is not null drop table SharedData create table dbo.SharedData ( experiment_year int, experiment_month int, rn int, calculated_number int, primary key (experiment_year, experiment_month, rn) ) go 现在,对于每个过程,我们都在表中保存了参数 if object_id('dbo.Params') is not null drop table dbo.Params create table dbo.Params ( session_id int, experiment_year int, experiment_month int, …

1
为什么在存储过程的末尾截断临时表以更快地创建其可用的tempdb空间?
SQL Server缓存在存储过程中创建的临时表,并仅在过程结束并随后执行时重命名它们。我的问题与何时释放tempdb空间有关。我已经知道该表在过程结束时被截断了。我已经读到评论说,这是基于每个会话进行处理的,并且看到了有关是否需要在MSDN上进行清理的问题。但是,如果它从未在同一会话中两次执行过,该怎么办? 我还听说过,有一个后台垃圾收集过程,一旦表超出范围,就会释放该空间。 尽管有相反的预期,但在创建存储过程的末尾截断一个临时表时,似乎导致该表在tempdb中用于释放数据的空间比没有使用truncate语句时要快。为什么? 使用或不使用这样的截断语句对性能的影响是什么?使用SNAPSHOT隔离时,经常会感到tempdb压力,我认为尽快从大型temp表中释放tempdb中使用的空间将防止tempdb的不必要增长。这种潜在的空间节省是以性能为代价的吗? 这是一些重现此问题的代码(主要来自@TheGameiswar,但有一些更改): SET NOCOUNT ON; GO ALTER PROC usp_test AS BEGIN IF object_id('tempdb..#temp') IS NOT NULL DROP TABLE #temp SELECT * INTO #temp FROM [dbo].[Event_28] -- This is a table with 15313 rows, using 35648 KB according to sp_spaceused --SELECT SUM(user_object_reserved_page_count) AS [user object pages used] …

2
查找数据库中所有表的未压缩大小
在Dynamics AX中,存在一种缓存机制,可以将表配置为加载到内存中并进行缓存。此高速缓存限制为一定数量的KB,以防止出现内存问题。我正在谈论的设置被调用,entiretablecache并在请求单个记录时立即将整个表加载到内存中。 直到最近,我们还是依靠一些脚本来验证具有此设置的表的大小,以查看表大小是否超过此限制。 现在,压缩开始发挥作用,像sp_spaceused或sys.allocation_units之类的东西似乎报告了压缩数据实际使用的空间。 显然,应用程序服务器正在处理未压​​缩的数据,因此SQL Server中磁盘上的数据大小无关紧要。我需要未压缩数据的实际大小。 我知道sp_estimate_data_compression_savings,但是顾名思义,这只是一个估计。 我希望尺寸尽可能正确。 我能想到的唯一方法是一些复杂的动态SQL创建与压缩表具有相同结构的未压缩表,将压缩数据插入该影子表中,然后检查该影子表的大小。 不用说,这有点乏味,并且需要花费一些时间才能在数百GB的数据库上运行。 Powershell可能是一个选项,但是我不想遍历所有表以select *对它们执行操作以检查脚本中的大小,因为那样只会淹没缓存,并且可能还需要很长时间。 简而言之,如果可能的话,我需要一种获取每个表大小的方法,因为一旦将其解压缩,就可以将碎片从呈现给应用程序的方程式中分离出来。我对各种方法持开放态度,首选使用T-SQL,但我不反对Powershell或其他创造性方法。 假设应用程序中的缓冲区是数据的大小。bigint始终是bigint的大小,并且字符数据类型为每个字符2个字节(unicode)。BLOB数据也占用数据的大小,枚举基本上是int,数字数据是numeric(38,12),datetime是datetime的大小。另外,没有NULL值,它们要么存储为空字符串,要么存储1900-01-01为零。 没有有关如何实现此方法的文档,但是这些假设是基于一些测试以及PFE和支持团队使用的脚本(显然,它们也忽略了压缩,因为检查是在应用程序中构建的,而应用程序无法分辨(如果基础数据已压缩),这还将检查表大小。例如,此链接指出: 避免对大型表使用EntireTable缓存(在AX 2009中超过128 KB或16页,在AX 2012中超过“整个表缓存大小”应用程序设置[默认值:32KB或4页])–改为记录缓存。

3
SQL Server日志是否记录未提交的操作?
我经常看到像sql server log这样的语句记录每个事务和操作。 但我感到困惑,当交易最终会发生什么滚 回去。 说,一个明确的事务有3个语句:statement A,statement B,statement C,最后一个rollback statement D。 现在说,当执行尚未达到时rollback statement D,将statements A through C记录到sql服务器的修改结果记录到日志中吗? 理解1: 语句A到D都被记录下来。无论如何,SQL Server都会记录所有内容。 理解2:修改仅存储在内存中的某个位置,并且仅在SQL Server看到一条commit语句时才记录到日志中。如果事实证明它是rollback语句,则SQL Server只会忽略事务,不会写入日志,因为它没有任何作用。换句话说,SQL Server时,有一个记录净结果之前和之后的交易。 两者似乎合乎逻辑,至少在我看来,但两者都不对。谢谢你的帮助。
12 sql-server 

3
为什么并行(分区流)运算符会将行估计值减少到1?
我正在使用SQL Server 2012 Enterprise。我遇到了一个SQL计划,该计划表现出一些我不完全直观的行为。在执行大量并行索引扫描操作之后,发生了并行(分区流)操作,但是该操作杀死了索引扫描(Object10.Index2)返回的行估计,从而将估计值减小为1。我已经做了一些搜索,但是还没有遇到任何可以解释这种现象的信息。查询非常简单,尽管每个表都包含数百万的记录。这是DWH加载过程的一部分,整个中间数据集都被触及过几次,但是我遇到的问题尤其与行估计有关。有人可以解释为什么并行(Repartition Strems)运算符中的精确行估计为1吗?也, 我已经发布了完整的计划以粘贴计划。 这是有问题的操作: 在添加更多上下文的情况下包括计划树: 我能否碰到Paul White提交的Connect项目的一些变体(在此处,他的博客有进一步的深入探讨)?至少这是我发现的唯一一件事,即使没有TOP运算符,它似乎也几乎接近我所遇到的问题。

5
根据前一个月末的值填充丢失的数据
给定以下数据: create table #histories ( username varchar(10), account varchar(10), assigned date ); insert into #histories values ('PHIL','ACCOUNT1','2017-01-04'), ('PETER','ACCOUNT1','2017-01-15'), ('DAVE','ACCOUNT1','2017-03-04'), ('ANDY','ACCOUNT1','2017-05-06'), ('DAVE','ACCOUNT1','2017-05-07'), ('FRED','ACCOUNT1','2017-05-08'), ('JAMES','ACCOUNT1','2017-08-05'), ('DAVE','ACCOUNT2','2017-01-02'), ('PHIL','ACCOUNT2','2017-01-18'), ('JOSH','ACCOUNT2','2017-04-08'), ('JAMES','ACCOUNT2','2017-04-09'), ('DAVE','ACCOUNT2','2017-05-06'), ('PHIL','ACCOUNT2','2017-05-07') ; ...表示何时将给定用户分配给帐户。 我正在寻找谁在每个月的最后一天(分配的日期是该帐户转移所有权的日期)拥有给定帐户的人,并填充所有缺少的月末(可能是从dates我可用的便捷表中创建的,具有有用的列DateKey,Date并且LastDayOfMonth,[由@AaronBertrand提供] 1。 理想的结果将是: PETER, ACCOUNT1, 2017-01-31 PETER, ACCOUNT1, 2017-02-28 DAVE, ACCOUNT1, 2017-03-31 DAVE, ACCOUNT1, 2017-04-30 FRED, ACCOUNT1, 2017-05-31 FRED, …

2
缺少存储过程的执行计划
存储过程的缓存中缺少计划的原因是什么? WITH RECOMPILE 动态SQL 加密代码 重大数据更改 更新统计 还有什么? 我最近在2台服务器(SQL Server 2008 R2和SQL Server 2012)上工作,这些服务器在缓存中没有计划用于非常占用资源的存储过程。存储过程中的许多(也许是全部)语句在缓存中也没有计划。一些存储过程非常频繁地执行,例如每秒执行几次。 没有任何记忆压力。其中一台服务器的硬件远远超出了所需。 我认为丢失的计划是由于在存储过程中间创建了临时表,但这似乎是来自SQL Server 2000或更早版本的旧信息。从SQL Server 2005开始,重新编译在DDL之后的语句的语句级别进行。在所有情况下都是如此吗,还是在新版本中仍然会发生? 遗失计划的罪魁祸首是什么?我已经浏览了有关该主题的几篇文章,但似乎没有什么合适的选择。 我本周要查看的服务器上启用了针对临时工作负载的优化。其中一个存储过程每天仅执行一次。我确实有那个的代码。我没有每分钟执行100次以上的代码,但我可以理解。我将无法发布代码,但是我可以根据自己的问题进行描述。 我不相信任何人都可以释放过程高速缓存或删除干净的缓冲区。该客户正在使用Solarwinds DPA作为其监视工具之一。DPA确实在每天被调用的存储过程中捕获了该语句的执行计划之一。由于不可保留的WHERE子句,该语句具有大量读取。如果DPA捕获了该语句,则它是一个估计的计划,并且一次在计划缓存中。当我们进行故障排除时,只是不存在。我将让他们开始记录sp_WhoIsActive到表中。 我正在使用sp_BlitzCache。(我为Brent Ozar Unlimited工作)将显示整个存储过程的计划以及单个语句(如果存在)的计划。如果它们不存在,则会发出警告“我们找不到该查询的计划。可能的原因包括动态SQL,RECOMPILE提示和加密代码。” 声明上也有警告。 TF 2371未安装。我正在查看等待统计信息。服务器很无聊。PLE超过130,000。 我现在有另外2个存储过程的代码。其中之一是使用动态SQL,exec (@sql)这样我们就知道为什么没有针对它的计划。但是另一种(每分钟运行100次以上)没有任何异常。唯一突出的一点是,临时表是在超过1000行代码的中间创建的。它也确实调用了一堆子存储过程。 关于SQL Server 2008中的计划缓存,我没有看到任何> = 8k的文字,但是其中一个存储过程在调用另一个存储过程之前就对批量插入发表了评论。但是批量插入没有出现在我正在查看的外部存储过程中。本文的“重新编译阈值”部分很有趣。我看到的临时表是大量的INSERT(可能导致数百万行),一些更新和删除。因此,大量数据更改到临时表。百万。

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.