Questions tagged «sql-server»

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

3
如何选择组中每列的最后一个非NULL值集?
我正在使用SQL Server 2016,并且正在使用的数据具有以下形式。 CREATE TABLE #tab (cat CHAR(1), t CHAR(2), val1 INT, val2 CHAR(1)); INSERT INTO #tab VALUES ('A','Q1',2,NULL),('A','Q2',NULL,'P'),('A','Q3',1,NULL),('A','Q3',NULL,NULL), ('B','Q1',5,NULL),('B','Q2',NULL,'P'),('B','Q3',NULL,'C'),('B','Q3',10,NULL); SELECT * FROM #tab; 我想要获取列上最后的非空值,val1并按进行val2分组cat和排序t。我正在寻找的结果是 cat val1 val2 A 1 P B 10 C 我所使用的最接近的是正在使用的,LAST_VALUE而忽略了ORDER BY那将不起作用,因为我需要排序的最后一个非空值。 SELECT DISTINCT cat, LAST_VALUE(val1) OVER(PARTITION BY cat ORDER BY (SELECT NULL) ) AS val1, …

5
Ola的脚本与使用维护计划的利弊是什么?
您能否帮助我了解在维护计划中使用Ola解决方案的利弊?我已经准备了一个基于SQL Pass的演示文稿(http://www.pass.org/DownloadFile.aspx?File=ebae1b31)。 我还准备了Ola解决方案无法解决的方案和维护计划解决方案所无法解决的方案。能否请大家帮我更详细地解释一下? 顺便说一下,我们管理着至少150%的服务器(2008/2012/2014/2016混合服务器),其中至少有75%使用Ola的解决方案。我喜欢Brent Ozar的这篇文章。但在评论中,Brent建议针对我们拥有的服务器数量使用基于脚本的解决方案。https://www.brentozar.com/archive/2012/04/maintenance-plans-roombas-suck-good-way/

3
非聚集索引是否对行顺序有任何保证?
我有一个开发人员希望在不按顺序执行select语句时,将表中的行按插入的顺序排列。开发人员建议从聚簇索引更改为非聚簇索引。 通过将索引从聚集索引更改为非聚集索引,这是否可以保证表中行的出现顺序? 这个问题主要是出于我的好奇心。我将建议改用Identity列,但是这个请求让我开始思考。可以使用时间戳,但是有可能同时插入行。 在此先感谢您的帮助。

2
连接到本地主机时,SMO,SSMS对于在Docker中管理SQL Server的速度很慢
TL; DR:当通过可解析为IPv6环回(::1)的名称连接到我的SQL Server Docker容器时,SMO调用确实很慢。使用时127.0.0.1,速度很快。 我正在尝试学习如何使用Docker镜像microsoft / mssql-server-windows-developer。根据Microsoft的文档,此容器仅公开端口1433 TCP。 docker run -d -p 1433:1433 -e sa_password=Passw0rd! -e ACCEPT_EULA=Y -v C:\dockerdb:C:\dockerdb microsoft/mssql-server-windows-developer 我正在Windows 10上运行该容器,并且已成功启动该容器,使用SQL Server身份验证进行身份验证,并在Windows主机上使用sqlcmd和SSMS 17.4对实例运行查询(连接到localhost或“。”),以及SQL操作通过IP连接的隔壁Mac上的Studio。这样运行查询时,我看不到任何明显的性能问题。 在SSMS中,我也可以浏览对象资源管理器,但是如果尝试从对象资源管理器中的对象的右键菜单上执行某些操作,例如打开实例参数窗口或附加数据库,则SSMS不会显示约5的响应-10分钟,此时它要么显示我要的窗口,要么显示以下错误消息: 我还尝试使用SMO Scripter对象针对此实例进行一些PowerShell脚本编写,并看到相同的行为。PS脚本循环遍历数据库中的对象并将其脚本化为文件,并且可以相对较快地收集对象列表,但是每个单独的对象需要5-10分钟的时间来编写脚本-太慢了,无法使用。 我有一个预感,即单个暴露的端口还不够,SMO和SSMS试图以类似的方式进行连接,这会使它们变慢。难道是当连接到本地主机时,这些工具是否假定存在其他通常不会进行防火墙保护的通信通道?我可以使用其他任何连接参数吗?谁能验证我关于SSMS正在使用SMO或其他与SQL Server通信的假设? 更新:我仍在调查,但这似乎是围绕资源限制的Docker问题。这很令人困惑,因为大多数文档似乎都表明Windows容器没有任何默认资源限制(并且不能在Docker for Windows GUI中设置这些默认资源限制- 仅对于Linux容器),但是实际上,Windows在Windows 10上运行的容器的默认RAM分配为1GB。我仍在尝试找出如何检查正在运行的容器以查看其RAM和CPU分配的方法,但是接下来我必须尝试使用docker run参数从默认值中增加这些值。 进一步更新:我一直无法从docker获得任何可靠的指标,该指标可以告诉我该容器对CPU和内存的限制。各种研究表明,docker容器默认没有内存限制,或者它们有1GB,但是我目前只能验证的是,docker stats该SQL容器仅使用 750到850兆之间,何时我尝试添加一个运行参数来将可用内存设置为4 GB,但出现错误。因此,我不再关注该查询线程,而是进行了另一项肠道检查:在正在运行的容器上进入交互式Powershell会话,然后从容器内部调用上面链接的Powershell脚本。 在容器内运行没有问题。它在短短几分钟内就烧穿了2780个物体。我认为这可以确认问题出在容器/主机边界上,因此我将看看是否可以打开该UDP端口。更新:打开端口1434 UDP没有帮助。 更多更新-已解决,而不是资源约束问题:似乎与为Windows容器设置大的内存分配有关的问题 -我在3g和2g上收到类似的错误,但最终能够从1.5g启动该容器,并且我发现docker stats容器的差异(我认为)证实了容器运行时的默认分配为1GB。在默认设置下,PRIV WORKING SET stat(我找不到任何文档,但我最大的猜测是它的RAM)在700MiB和850MiB之间。用docker run —memory="1.5g"设置,大约是1.0GiB。因此,它的确扩大了,但似乎腾出了比以前更多的分配空间。我将此解释(可能是错误地)是指该服务器(绝对没有负载运行并且没有用户数据库)没有内存压力。我检查了最大服务器内存设置,以确认它设置为默认的最大2PiB。 …

5
使用“ []”通配符将一个](右方括号)与PATINDEX匹配
我正在T-SQL †中编写自定义JSON解析器。 出于解析器的目的,我使用的PATINDEX功能是从标记列表中计算标记的位置。在我的情况下,标记都是单个字符,它们包括以下这些: {} []:, 通常,当我需要找到几个给定字符中任何一个的(第一个)位置时,我会使用如下PATINDEX函数: PATINDEX('%[abc]%', SourceString) 然后,该函数将为我提供aor b或or 的第一个位置c-两者中最先找到的那个SourceString。 现在,就我而言,问题似乎与]角色有关。一旦在字符列表中指定了它,例如: PATINDEX('%[[]{}:,]%', SourceString) 我的预期模式显然已损坏,因为该函数从未找到匹配项。看来我需要一种方法来转义第一个,]以便PATINDEX将其视为查找字符之一,而不是特殊符号。 我发现这个问题询问类似的问题: 需要LIKE运算符和方括号的帮助 但是,在那种情况下,]根本不需要在方括号中指定简单字符,因为它只是一个字符,可以在不带方括号的情况下进行指定。确实使用转义的替代解决方案仅针对LIKE而不适用PATINDEX,因为它使用了ESCAPE由前者而非后者支持的子句。 所以,我的问题是,有没有什么办法去寻找一个]与PATINDEX使用[ ]通配符?还是有一种方法可以使用其他Transact-SQL工具来模拟该功能? 附加信息 这是我需要PATINDEX与上述[…]模式一起使用的查询示例。这里的模式有效(尽管有点),因为它不包含]字符。我也需要使用它]: WITH data AS (SELECT CAST('{"f1":["v1","v2"],"f2":"v3"}' AS varchar(max)) AS ResponseJSON), parser AS ( SELECT Level = 1, OpenClose = 1, P = p.P, S = SUBSTRING(d.ResponseJSON, 1, NULLIF(p.P, 0) …

1
主表/明细表之间的哈希联接产生的基数估计值太低
将主表连接到明细表时,如何鼓励SQL Server 2014将较大(详细)表的基数估计用作联接输出的基数估计? 例如,当将10K主行连接到100K详细信息行时,我希望SQL Server估计100K行的联接-与详细信息行的估计数量相同。如何构造查询和/或表和/或索引,以帮助SQL Server的估计器利用每个详细信息行始终都有一个对应的主行这一事实?(这意味着它们之间的连接永远不会降低基数估计。) 这里有更多细节。我们的数据库有一个主/明细表对:VisitTarget每个销售交易VisitSale都有一行,而每个交易中每个产品都有一行。这是一对多的关系:一个VisitTarget行,平均10个VisitSale行。 这些表如下所示:(我将简化为该问题的相关列) -- "master" table CREATE TABLE VisitTarget ( VisitTargetId int IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED, SaleDate date NOT NULL, StoreId int NOT NULL -- other columns omitted for clarity ); -- covering index for date-scoped queries CREATE NONCLUSTERED INDEX IX_VisitTarget_SaleDate ON VisitTarget …

1
如何在不安装媒体的情况下卸载SQL Server 2014 Standard Edition?
几年来,我已经将SQL Server 2014 Standard的副本作为默认实例安装在我的开发框中。我在计算机上安装了standard,因为我可以通过MSDN订阅使用免费许可证。现在我想卸载SQL Server 2014,并将SQL Server 2017 Developer Edition设置为默认实例。我试图通过标准的“添加/删除程序”工作流来卸载SQL Server 2014,但是在询问我要卸载哪些功能后,它提示我输入包含卸载媒体的目录。不幸的是,我没有保存从MSDN获得的SQL Server 2014下载程序包,并且我再也无法访问MSDN。我还检查了My Visual Studio,但它只能追溯到SQL Server2016。如何在没有安装媒体的情况下卸载SQL Server 2014 Standard? 进一步的背景: 我想要卸载SQL Server 2014的全部原因是我想使用STRING_AGGAzure SQL数据库和SQL Server 2017的新功能。为了使设置开发环境更加容易,我们对本地环境开发连接字符串使用点符号,例如我们的连接字符串是: Data Source=.;Initial Catalog=<Database Name>;Trusted_Connection=True;Connection Timeout=30; 点符号连接到默认数据库,据我所知,如果不先卸载SQL Server 2014,就无法将SQL Server 2017设置为默认数据库。如果我可以使用点表示法连接字符串连接到SQL Server 2017,而无需卸载SQL Server 2014,那么我也愿意使用该解决方案。

2
在msdb上启用查询存储有什么好处?
在SQL系统数据库(主数据库,模型数据库,msdb数据库,tempdb数据库)中,查询存储只能在msdb上使用。我查看了,没有找到有关msdb上查询存储的任何文档。 虽然您无法在GUI中看到它,但可以在您的SQL 2016实例上对其进行验证 验证查询存储已关闭 USE msdb SELECT * FROM sys.database_query_store_options; 开启查询存储 USE [master] GO ALTER DATABASE msdb SET QUERY_STORE = ON GO ALTER DATABASE msdb SET QUERY_STORE (OPERATION_MODE = READ_WRITE , INTERVAL_LENGTH_MINUTES = 30 , MAX_STORAGE_SIZE_MB = 1000 , QUERY_CAPTURE_MODE = AUTO) GO 验证查询存储已打开 USE msdb SELECT * FROM sys.database_query_store_options; …

3
从SQL表中删除数百万行
我必须从221+百万行表中删除16+百万条记录,并且运行非常缓慢。 多谢您分享建议,以加快以下代码的速度: SET TRANSACTION ISOLATION LEVEL READ COMMITTED; DECLARE @BATCHSIZE INT, @ITERATION INT, @TOTALROWS INT, @MSG VARCHAR(500); SET DEADLOCK_PRIORITY LOW; SET @BATCHSIZE = 4500; SET @ITERATION = 0; SET @TOTALROWS = 0; BEGIN TRY BEGIN TRANSACTION; WHILE @BATCHSIZE > 0 BEGIN DELETE TOP (@BATCHSIZE) FROM MySourceTable OUTPUT DELETED.* INTO MyBackupTable …

3
如何提示SQL Server中的多对多联接?
我有3个“大”表,它们连接在一对列(均为int)上。 Table1拥有约2亿行 Table2拥有约150万行 Table3拥有约600万行 每个表都有一个聚集索引Key1,Key2以及再得一列。Key1具有低基数并且非常偏斜。WHERE子句中始终引用它。条款中Key2从未提及WHERE。每个联接都是多对多的。 问题在于基数估计。每个连接的输出估计值变小而不是变大。当实际结果达到数百万时,最终得出的结果估计只有几百个。 我有什么办法让行政长官提示做出更好的估计? SELECT 1 FROM Table1 t1 JOIN Table2 t2 ON t1.Key1 = t2.Key1 AND t1.Key2 = t2.Key2 JOIN Table3 t3 ON t1.Key1 = t3.Key1 AND t1.Key2 = t3.Key2 WHERE t1.Key1 = 1; 我尝试过的解决方案: 在创建多列统计Key1,Key2 创建大量已过滤的统计信息Key1(这很有帮助,但是我最终在数据库中获得了数千个用户创建的统计信息。) 掩盖的执行计划(抱歉掩盖不好) 就我而言,结果有900万行。新的CE估计有180行;旧版CE估计有6100行。 这是一个可重现的示例: DROP TABLE IF EXISTS #Table1, #Table2, …

2
查询性能调优
寻求帮助来改善此查询性能。 SQL Server 2008 R2 Enterprise,最大RAM 16 GB,CPU 40,最大并行度4。 SELECT DsJobStat.JobName AS JobName , AJF.ApplGroup AS GroupName , DsJobStat.JobStatus AS JobStatus , AVG(CAST(DsJobStat.ElapsedSec AS FLOAT)) AS ElapsedSecAVG , AVG(CAST(DsJobStat.CpuMSec AS FLOAT)) AS CpuMSecAVG FROM DsJobStat, AJF WHERE DsJobStat.NumericOrderNo=AJF.OrderNo AND DsJobStat.Odate=AJF.Odate AND DsJobStat.JobName NOT IN( SELECT [DsAvg].JobName FROM [DsAvg] ) GROUP …

1
服务经纪人-对话寿命?
我们正在努力使Service Broker在我们的环境中工作,以解决业务案例。我不知道消息标题是否是一个好标题,但是我的问题在下面。但这可能不是一个好问题,所以在那之后我们要做的就是为什么我认为这是正确的问题。 在结束对话之前,应在对话中发送多少条消息? 我们要使用Service Broker来异步更新结果表。结果表平坦且快速。我们在基表上具有触发器,该触发器发送带有其表和主键的消息。我们有三个队列: 低延迟-目标是处理15秒。它处理与特定项目有关的更改项目。 批量队列-目标是5分钟的处理时间。它处理何时会影响数百(或数千)个项目的更改。它列出了受影响的项目列表,并将其馈入“延迟的低延迟队列” 延迟的低延迟-目标是30分钟才能处理。这仅处理批量队列中的项目。 基本上,如果客户的信息更新;这会影响许多产品,因此将其发送到批量队列以减慢处理速度。但是,如果产品得到更新,则将其发送到低延迟队列。 我们重用类似于Remus Rusanu的博客http://rusanu.com/2007/04/25/reusing-conversations/的对话,不同之处在于我们是基于主键的模数来进行对话的。这具有辅助主键重复数据删除的附带好处。 因此,我们正在重新使用对话并且在我们的准则之内。通过两个线程,我能够每秒刻录125条消息(人为丢弃几千条消息),这远远超过了保持生产的速度(每秒15条消息)。 但是,我们遇到的问题是,经过一段时间,大约4个小时或120K消息,我们开始在sysdesend和队列表上看到块和高争用。锁是LCK_M_U,是KEY锁。有时,宏块解析为sysdesend,有时解析为特定的队列表(queue_)。 我们已经制定了一个流程,该流程将在闲置24小时或30分钟后结束对话,因此我们可以增加循环讨论之前的时间。 我们正在使用SQL 2016 Enterprise(13.0.4001.0) 触发触发(发送低延迟或批量发送) 查找或创建对话句柄。 发信息 队列激活过程 更新结果表 清理过程每10分钟运行一次,以查看是否有空闲的对话。如果连续超过三遍发现它们,则将其标记为无效并结束对话。 请让我知道是否还有其他可能有益的细节。我在Service Broker方面没有太多经验,所以我不知道我们的消息/秒是低,高还是无动于衷。 更新 因此,我们今天再次尝试,并遇到了相同的问题。我们将对话寿命更改为2小时,但没有任何效果。因此,我们实施了150招;有同样的问题。 大量等待SEND CONVERSATION,等待sysdesend。有人还有其他想法吗? 更新2 今天我们进行了更长的测试,并且在17分钟的采样期间之一中,我们在4个会话句柄上处理了41K条消息。当sysdesend上的锁和队列表变得过多,并且在停止它之前我们开始向后漂移时,我们能够保持到最后。我们似乎在处理消息方面没有问题,没有任何东西进入队列,我们​​可以将其拉出并以至少5倍的速度处理它们。基于添加消息,我们的速度似乎受到限制。 在以后的测试中,我们删除了占消息总数80%的触发器之一。即使负载大大减少,我们也开始看到相同的等待。 更新3 谢谢Remus的建议(也感谢您发布有关该主题的出色博客文章,它们对于达到这一点很有帮助)。 我们今天再次运行它,并且表现更好(因为在等待之前,我们走了更长的时间,甚至在我们瘫痪之前走了更长的时间)。所以,细节。 我们更改了:*将每个线程的可维护会话数从1:1增加到2:1。基本上,我们有4个线程的8个会话句柄。 合并大容量队列(因为一条传入消息可能意味着数百条传出消息),从而合并为更少,更大的消息。 关于此尝试的注意事项: 禁用目标队列激活过程。阻塞没有变化(我们等待了5分钟),消息确实发送到了sys.transmission_queues。 监视sys.conversation_endpoints。这个数字从0很快就达到了13K,然后全天缓慢上升,直到大约5小时后才达到25K。直到达到16K +/-才开始阻塞 我进入DAC并为队列运行DBREINDEX命令,尽管通过查询,幻象记录在进行清理并将计数降至0之前从未超过200左右。 当我结束测试时,sysdesend和sysdercv的计数相同,为24,932。 我们在5个小时内处理了约310K条消息。 我们走了很长时间,事情才崩溃了,我真的以为这次可以做到。明天我们将尝试强制消息通过网络。


1
sp_cursorprepexec导致5300万次读取?
我们正在使用SQL Server 2012运行Dynamics AX 2012安装。我知道不应再使用游标,但是AX正在使用它,并且我们无法更改此行为,因此必须使用它。 今天,我遇到了一个非常糟糕的查询,读取次数超过5300万,执行时间超过20分钟。 我通过我们的监视工具SentryOne捕获了此查询。 declare @p1 int set @p1=1073773227 declare @p2 int set @p2=180158805 declare @p5 int set @p5=16 declare @p6 int set @p6=1 declare @p7 int set @p7=2 exec sp_cursorprepexec @p1 output,@p2 output,N'@P1 bigint,@P2 nvarchar(5),@P3 bigint,@P4 nvarchar(8),@P5 bigint,@P6 bigint,@P7 bigint,@P8 bigint,@P9 bigint,@P10 bigint,@P11 bigint,@P12 bigint,@P13 bigint,@P14 …


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.