数据库管理员

希望提高数据库技能并向社区中的其他人学习的数据库专业人员的问答

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

1
夏令时
在我的环境中,有一些服务器在本机备份和Ola Hallengren计划上运行。我们的服务器是2008年,2012年和2014年的组合。所有完整备份均在凌晨12点进行,日志备份每15分钟进行一次。 我以前从未考虑过夏令时,因此请告诉我应该进行哪些调整。 凌晨12点的完整备份会受到影响吗?日志备份会怎样?

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 …


1
在Postgres中清零WAL段
我们有一个相对较小的Postgres数据库,该数据库具有连续归档功能,可以压缩每个WAL段并将其发送到S3。因为它是一种低容量系统,所以它archive_timeout每10分钟左右命中一次,并存档大部分未使用的WAL段,该段过去压缩得很好,因为它几乎只是零。 但是,Postgres回收其WAL段,以避免在每个WAL交换机上分配新文件的成本,这在高负载情况下很有用,但是这意味着在发生了比平常多的活动之后,我们的WAL段文件现在已满来自先前片段的垃圾,并且压缩效果不佳。我们正在存储所有这些垃圾的许多副本。 有没有一种方法可以减少我们用来保存WAL存档的空间?一些次优的可能性: 防止Postgres以某种方式回收WAL段,因此每次以零文件开始。该文档没有表明有这样做的选项,但我可能会错过它。 启动/完成使用后,使Postgres将WAL段文件归零。同样,文档似乎并不暗示这是可能的。 在不使用它们时从外部将其清除或删除一些WAL段文件。有没有安全的方法来确定这是哪个文件? 将段的未使用部分归零,然后使用from的输出pg_xlogdump将其归档,以查找垃圾从何处开始。可能,尽管我不喜欢它。至少通过在archive命令中执行此操作,可以确保Postgres不会重用该文件。 仅通过解释pg_xlogdump某种方式的输出来再次归档段文件的使用部分,然后在还原期间将其填充零。虽然我不太喜欢它,但听起来也可能。

3
自联接主键
考虑以下由N自我联接组成的查询: select t1.* from [Table] as t1 join [Table] as t2 on t1.Id = t2.Id -- ... join [Table] as tN on t1.Id = tN.Id 它生成具有N个聚集索引扫描和N-1个合并联接的执行计划。 老实说,我看不出没有理由不优化所有联接而仅执行一个聚集索引扫描,即为此优化原始查询: select t1.* from [Table] as t1 问题 为什么没有优化联接? 说每个联接都不会改变结果集在数学上是不正确的吗? 经过测试: 源服务器版本:SQL Server 2014(12.0.4213) 源数据库引擎版本:Microsoft SQL Server标准版 源数据库引擎类型:独立SQL Server 兼容性级别:SQL Server 2008(100) 查询没有意义;它只是浮现在我的脑海,我对此感到很好奇。 这是创建表和3个查询的小提琴:带有inner …


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.