作为旧版修复计划的一部分,我们已将应用程序数据库从 Windows 2003 上运行的旧 SQL Server 2000 实例迁移到 Windows 2022 上运行的新 SQL Server 2022 实例。应用程序层有许多在 Windows 上使用 IIS 6.0 的 Web 服务器2003 年,当他们尝试测试与新 SQL Server 的连接时,他们收到以下 SSL 安全错误。知道这里可能是什么问题吗,是否可能是驱动程序(下面的屏幕截图显示了网络服务器上安装的驱动程序)?或者是否可能与双方启用的 SSL/TLS 版本有关?
Fza's questions
我有一个 SQL Server 2017 企业版实例,其中存储过程大约需要。五分钟执行。查看存储过程代码后,我可以看到在 SELECT 列表和存储过程主体的谓词 WHERE 子句中多次引用了一个内联标量 UDF。
我建议拥有代码的应用程序团队应该重构他们的存储过程,不要使用他们采用的内联 UDF,并用 TVF 替换。在他们这样做的同时,我注意到应用程序数据库的数据库兼容性级别仍然为 100,因此在通过数据迁移助手运行数据库以检查已弃用的功能和重大更改后,我将其提升到最新的 140 级别。
在将 UDF 替换为 TVF 并将数据库兼容性级别从 100 提高到 140 之后,性能有了很大的提高,现在存储的 proc 可以在不到一分钟的时间内执行,但性能仍然不是我想要的。我希望有人能够就我遗漏的任何明显的事情提出建议,或者指出我可以做的任何其他事情的正确方向,以进一步优化代码或让它表现得更好?执行计划在这里:https ://www.brentozar.com/pastetheplan/?id=ByrsEdRpr
存储过程和函数的代码如下,存储过程由应用程序调用:“EXEC dbo.CAOT_GetApplicationQueue;1”
/****** Object: StoredProcedure [dbo].[CAOT_GetApplicationQueue] ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[CAOT_GetApplicationQueue]
(@userID VARCHAR(50)='', @showComplete CHAR(1)='N', @JustMyQueue BIT=0, @ChannelId VARCHAR(10) = NULL )
AS
BEGIN
SELECT App.pkApplication ,
COALESCE(ApplicationReference, AlternateApplicationReference) AS ApplicationReference ,
ApplicationDate ,
Name ,
Telephone ,
[Address] ,
Email ,
CIN ,
Dob ,
CreatedDate ,
BusinessPhone ,
PostCode ,
MobilePhone ,
[Action] ,
ActionStatus ,
branchNumber ,
AccountNumber ,
AccountType ,
act.accountDescription,
IsNull( appstatus.DESCRIPTION ,'-- CREATED --') As LastStatus,
IsNull(appstatus.DAYS,'0') DaysSinceLastStatus ,
DATEDIFF(d,ApplicationDate, GETDATE()) DaysCreated,
InitialUserID,
IsNull(appstatus.STATUS,'-- MADE --') APPLICATIONSTATUS
FROM dbo.CAOT_Application (NOLOCK) app
LEFT OUTER JOIN dbo.CAOT_AccountType (NOLOCK) act
ON app.AccountType = act.AccountTypecode
LEFT OUTER JOIN [CAOT_GetAllApplicationStatus]() appstatus
ON app.pkApplication = appstatus.[PKAPPLICATION]
WHERE (IsNull(appstatus.STATUSCODE,'MADE') NOT IN ('CANCELLED','DECLINED','COMPLETE','EXPIRED')
OR @showComplete='Y') AND
(@JustMyQueue = 0 OR InitialUserID = @userID) AND
(@ChannelId IS NULL OR ChannelID = @ChannelId OR (@ChannelId = 'CBU' AND ChannelID IS NULL AND isCAO='N'))
ORDER BY CASE WHEN InitialUserID = @userid THEN 10 ELSE 900 END, ApplicationDate DESC
END
GO
/****** Object: UserDefinedFunction [dbo].[CAOT_GetAllApplicationStatus] ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[CAOT_GetAllApplicationStatus]() RETURNS
@return TABLE
(
[PKAPPLICATION] [int] NOT NULL,
[PKAPPLICATIONEVENT] INT,
[EVENTCREATEDDATE] [DATETIME] NULL,
[KEY] VARCHAR(12) NULL,
[DESCRIPTION] VARCHAR(200) NULL,
[CODE] VARCHAR(20) NULL,
[DAYS] VARCHAR(20) NULL,
[STATUS] VARCHAR(200) NULL,
[STATUSCODE] VARCHAR(50) NULL
)
AS
BEGIN
Declare @AppStatus table
(
[PKAPPLICATION] [int] NOT NULL,
[PKAPPLICATIONEVENT] INT,
[EVENTCREATEDDATE] [DATETIME] NULL,
[KEY] VARCHAR(12) NULL,
[DESCRIPTION] VARCHAR(200) NULL,
[CODE] VARCHAR(20) NULL,
[DAYS] VARCHAR(20) NULL,
[STATUS] VARCHAR(200) NULL,
[STATUSCODE] VARCHAR(50) NULL
)
INSERT INTO @AppStatus
SELECT
fkApplication,
ev.pkApplicationEvent As pkApplicationEvent,
ev.CreateDate As 'EventCreatedDate',
CONVERT(VARCHAR(12), evt.fkApplicationStatus) As 'KEY',
evt.EventDescription As 'DESCRIPTION',
evt.EventCode As 'CODE' ,
CONVERT(VARCHAR(20), DATEDIFF(d, ev.createdate, GETDATE()) ) As 'DAYS',
apps.StatusDescription As 'STATUS' ,
apps.StatusCode As 'STATUSCODE'
FROM dbo.CAOT_ApplicationEvent (NOLOCK) ev
INNER JOIN dbo.CAOT_EventType (NOLOCK) evt ON ev.fkEventType = evt.pkEventType
INNER JOIN dbo.CAOT_ApplicationStatus (NOLOCK) apps ON evt.fkApplicationStatus = apps.pkApplicationStatus
ORDER BY ev.CreateDate DESC, ev.pkApplicationEvent DESC
INSERT INTO @return
Select * from @AppStatus AllStatus
Where AllStatus.EVENTCREATEDDATE = ( Select Max(LatestAppStatus.EVENTCREATEDDATE) from @AppStatus LatestAppStatus where LatestAppStatus.PKAPPLICATION =AllStatus.PKAPPLICATION ) --Z On X.PKAPPLICATION = Z.PKAPPLICATION
RETURN
END
GO
我正在尝试调整以下查询,无论作为参数传入什么值,都需要 15-16 秒,查询是:
select distinct d.documentpath as path, d.documentname as name, d.datecreated as created, pc.DateProcessed
from datagatheringruntime dgr
inner join processentitymapping pem on pem.entityid = dgr.entityid
inner join document d on d.entityid = pem.entityid or d.unitofworkid = pem.processid
left join PendingCorrespondence pc on pc.PendingCorrespondenceId = d.PendingCorrespondenceId
where rootid = @P0 and dgr.name in('cust_pn', 'case_pn')
OPTION(RECOMPILE)
我已经更新了查询所涉及的所有表的统计信息(不包括DataGatheringRuntime
在 ~ 处很大的表100GB
),并尝试使用 a 重构查询,CTE
但获得了相同的执行计划并需要一些帮助。
实际的执行计划可以在这里找到:
https://www.brentozar.com/pastetheplan/?id=ByUVIqlFE
从执行计划中可以清楚地看出,问题出在表上的非聚集索引之后的外部输入上nested loop join
,但我不知道如何解决该问题,并希望得到任何指导。lazy table spool
scan
IX_Camunda_1
Document
我在 SQL Server 2016 EE 实例上有一个 550GB 的相对较大的数据库,在操作系统可用的总 128GB RAM 中,最大内存限制为 112GB。该数据库的最新兼容性级别为 130。开发人员抱怨以下查询在单独执行时会在 30 秒的可接受时间内执行,但当他们大规模运行进程时,相同的查询会同时执行多次跨多个线程,这是他们观察到执行时间受到影响并且性能/吞吐量下降的时候。有问题的 T-SQL 是:
select distinct dg.entityId, et.EntityName, dg.Version
from DataGathering dg with(nolock)
inner join entity e with(nolock)
on e.EntityId = dg.EntityId
inner join entitytype et with(nolock)
on et.EntityTypeID = e.EntityTypeID
and et.EntityName = 'Account_Third_Party_Details'
inner join entitymapping em with(nolock)
on em.ChildEntityId = dg.EntityId
and em.ParentEntityId = -1
where dg.EntityId = dg.RootId
union all
select distinct dg1.EntityId, et.EntityName, dg1.version
from datagathering dg1 with(nolock)
inner join entity e with(nolock)
on e.EntityId = dg1.EntityId
inner join entitytype et with(nolock)
on et.EntityTypeID = e.EntityTypeID
and et.EntityName = 'TIN_Details'
where dg1.EntityId = dg1.RootId
and dg1.EntityId not in (
select distinct ChildEntityId
from entitymapping
where ChildEntityId = dg1.EntityId
and ParentEntityId = -1)
实际执行计划显示以下内存授予警告:
图形执行计划可以在这里找到:
https://www.brentozar.com/pastetheplan/?id=r18ZtCidN
以下是此查询涉及的表的行数和大小。最昂贵的运算符是对 DataGathering 表上的非聚集索引的索引扫描,考虑到与其他表相比的大小,这是有意义的。我理解为什么/如何需要内存授予,我认为这是由于查询的编写方式需要多个排序和哈希运算符。我需要的建议/指导是如何避免内存授予、T-SQL 和重构代码不是我的强项,有没有办法重写这个查询以提高性能?如果我可以将查询调整为单独运行得更快,那么希望这些好处会转移到大规模运行时,也就是性能开始受到影响的时候。很高兴提供更多信息,并希望从中学到一些东西!
更新 3 个表的统计信息后:
UPDATE STATISTICS Entity WITH FULLSCAN;
UPDATE STATISTICS EntityMapping WITH FULLSCAN;
UPDATE STATISTICS EntityType WITH FULLSCAN;
...执行计划改进了一些:
https://www.brentozar.com/pastetheplan/?id=rkVmdkh_4
不幸的是,“过度授权”警告仍然存在。
Josh Darnell 友好地建议将查询重新分解为以下内容,以避免他在某个运算符上发现的并行性受到抑制。重构查询引发错误“消息 4104,级别 16,状态 1,第 7 行无法绑定多部分标识符“et.EntityName”。” 我该如何解决这个问题?
DECLARE @tinDetailsId int;
SELECT @tinDetailsId = et.EntityTypeID
FROM entitytype et
WHERE et.EntityName = 'TIN_Details';
select distinct dg1.EntityId, et.EntityName, dg1.version
from datagathering dg1 with(nolock)
inner join entity e with(nolock)
on e.EntityId = dg1.EntityId
where dg1.EntityId = dg1.RootId
and e.EntityTypeID = @tinDetailsId
and dg1.EntityId not in (
select distinct ChildEntityId
from entitymapping
where ChildEntityId = dg1.EntityId
and ParentEntityId = -1)
UNION ALL
select distinct dg.entityId, et.EntityName, dg.Version
from DataGathering dg with(nolock)
inner join entity e with(nolock)
on e.EntityId = dg.EntityId
inner join entitytype et with(nolock)
on et.EntityTypeID = e.EntityTypeID
and et.EntityName = 'Account_Third_Party_Details'
inner join entitymapping em with(nolock)
on em.ChildEntityId = dg.EntityId
and em.ParentEntityId = -1
where dg.EntityId = dg.RootId
我正在对同步与异步自动统计更新进行一些测试。我想快速使所有统计对象(标题、密度向量和直方图)失效,以确保下次使用统计时会更新它。
我正在尝试模拟统计信息的自动更新,而不是自动创建。
理想情况下,我不想更改行数,所以我已经取消了INSERT/DELETE
操作。理想情况下,我也不想更改任何数据值,我考虑过使用UPDATE
语句,但我认为这在我的一些较大的表上可能会花费太长时间。
我看过UPDATE STATISTICS WITH ROWCOUNT, PAGECOUNT
但我不认为这是我所追求的。我希望可能有一个跟踪标志或未记录的命令会使统计信息无效。
有没有一种快速、有效的方法来完成我想实现但我没有考虑过的事情?
我正在 SQL Server 2016 上进行测试。
假设自动创建统计信息和自动更新统计信息的默认选项设置为 true,在 SQL Server 中下面的各种统计操作期间会采用哪些锁定?
- 自动创建统计对象
- 统计对象的自动更新
- 手动创建统计对象
- 手动更新统计对象
上面的场景1&2在统计设置为异步更新时,采取的锁有什么区别吗?
我的印象是,在LIKE
对未知场景进行所有优化时,旧版和新版 CE 都使用 9% 的估计值(假设相关统计数据可用并且查询优化器不必求助于选择性猜测)。
在对信用数据库执行以下查询时,我在不同的 CE 下得到不同的估计。在新的 CE 下,我收到了预期的 900 行的估计值,在旧版 CE 下,我收到了 241.416 的估计值,但我无法弄清楚这个估计值是如何得出的。有没有人能够阐明任何观点?
-- New CE (Estimate = 900)
DECLARE @LastName VARCHAR(15) = 'BA%'
SELECT * FROM [Credit].[dbo].[member]
WHERE [lastname] LIKE @LastName;
-- Forcing Legacy CE (Estimate = 241.416)
DECLARE @LastName VARCHAR(15) = 'BA%'
SELECT * FROM [Credit].[dbo].[member]
WHERE [lastname] LIKE @LastName
OPTION (
QUERYTRACEON 9481,
QUERYTRACEON 9292,
QUERYTRACEON 9204,
QUERYTRACEON 3604
);
在我的场景中,我已经将信用数据库设置为兼容级别 120,因此为什么在第二个查询中我使用跟踪标志来强制使用旧版 CE,并提供有关查询优化器使用/考虑哪些统计信息的信息。我可以看到正在使用“姓氏”的列统计信息,但我仍然无法计算出 241.416 的估计值是如何得出的。
除了这篇 Itzik Ben-Gan 文章外,我在网上找不到任何东西,该文章指出“在所有优化未知场景中使用 LIKE 谓词时,旧版和新版 CE 都使用 9% 的估计值。”。该帖子中的信息似乎不正确。
关于可用于减轻不良参数嗅探的某些方法,有很多极好的信息,但没有很多关于如何识别不良参数嗅探问题的信息。
假设您没有使用 SQL Server 2016,因此无法利用查询存储,并且您没有用户抱怨有问题的存储过程间歇性地执行不佳,那么可以使用哪些方法来主动识别错误的参数嗅探问题?
利用扩展事件、RML 实用程序和简单地查询/轮询 DMV 似乎都是可行的方法,有没有人有使用这些方法的方法或知道描述如何去做的任何好的资源?
我使用下面的 T-SQL 查询来确定上次完整数据库备份的日期,并返回备份文件的大小和位置。我的问题是,对于没有备份或没有备份历史记录的数据库,它根本不会返回任何数据。理想情况下,我想修改查询以便返回所有数据库,无论它们是否有任何备份历史记录。谁能建议如何修改以下查询以适应此情况?
WITH LastBackUp AS
(
SELECT bs.database_name,
bs.backup_size,
bs.backup_start_date,
bmf.physical_device_name,
Position = ROW_NUMBER() OVER( PARTITION BY bs.database_name ORDER BY bs.backup_start_date DESC )
FROM msdb.dbo.backupmediafamily bmf
JOIN msdb.dbo.backupmediaset bms ON bmf.media_set_id = bms.media_set_id
JOIN msdb.dbo.backupset bs ON bms.media_set_id = bs.media_set_id
WHERE bs.[type] = 'D'
AND bs.is_copy_only = 0
)
SELECT
database_name AS [Database],
CAST(backup_size / 1048576 AS DECIMAL(10, 2) ) AS [BackupSizeMB],
backup_start_date AS [Last Full DB Backup Date],
physical_device_name AS [Backup File Location]
FROM LastBackUp
WHERE Position = 1
ORDER BY [Database];
这是问题的后续: AlwaysON 可用性组 - 辅助副本节点的 IP 地址更改
同样的场景,可用性组处于同步提交模式,一个主副本和一个辅助副本在多子网配置中。集群节点是物理机器。由于硬件维护,次要副本集群节点使用的服务器正在移动,因此将离线并以不同子网中的不同IP地址重新上线。一个人将如何解决这个问题?
我最初的想法是:如果可能,将新的网络接口添加到辅助节点。使用不同子网中的新 IP 地址配置新网络接口。集群应该自动构建内部路由并注册新的网络接口。
在 FCM(故障转移集群管理器)中,一个新的集群网络将出现在“网络”选项卡下。在集群核心资源中,添加新网络并为集群 VNN 创建一个新的静态 IP 地址。应用更改然后返回并添加对新 IP 地址的 OR 依赖项。
在将删除旧 IP 地址/网络接口的服务器移动中断之前,在 FCM 中,返回集群核心资源,进入集群 VNN 的属性并删除旧网络/静态 IP 地址并删除对它。当服务器脱机并重新联机时,旧的网络接口对服务器不可见,也不会出现在 FCM 的网络选项卡中。任何集群资源都不应该有任何问题,因为对旧 IP/子网/网络的任何依赖都已删除。
还有什么需要考虑的吗?由于集群节点是物理的,这是否会使网络接口复杂化?通过在虚拟环境中进行测试,它显然得到了简化,因为移除和连接虚拟网络交换机很容易。
我有一个多子网 AlwaysON AG,其中一个主副本和一个辅助副本处于同步提交模式。由于硬件维护,辅助节点的 IP 地址会发生变化。
从 SQL Server、AlwaysON 可用性组和 WSFC 的角度来看,我应该采取什么行动或应该注意什么?
我有一个 AlwaysON AG,其中一个主副本和一个辅助副本处于同步提交模式。AG 中的数据库都禁用了自动增长(组织内的标准策略)。托管次要副本的服务器上有计划的硬件维护,这将导致服务器离线 4-8 小时。我的不理解是,当这种情况发生时,从属副本的连接状态将变为 DISCONNECTED,主副本中的数据库的发送队列会累积未发送的事务日志记录。只要辅助副本保持脱机,所有当前日志记录都保持活动状态(禁用自动增长),事务日志备份就不会截断日志,因为日志可能会被填满。有人可以确认这是否正确吗?有什么办法可以减轻这种情况,即。
这是我的理解,但是在阅读了这篇 msdn 文章https://msdn.microsoft.com/en-us/library/ff877931%28v=sql.110%29.aspx?f=255&MSPPError=-2147217396后我很困惑。有一条注释指出:“如果辅助副本超过了主副本的会话超时期限,则主副本会暂时切换到该辅助副本的异步提交模式。当辅助副本与主副本重新连接时,它们会恢复同步-提交模式。”
这是否与上述我的情况有关,如果是的话,这是否意味着交易完成的可能性被设计减轻了?在查询 sys.availabilty_replicas 或通过任何扩展事件时,是否可以看到提交模式的这种临时转变,或者它是纯粹的幕后变化?