我必须从生产数据库创建 DACPAC。我想通过 Visual Studio 2022(SQL Server 对象资源管理器和“提取 - 数据层应用程序”)来执行此操作。是否可以阻止任何进程/查询或利用更多 CPU/内存来执行此操作?
我有以下想要合并的 JSON。在我的 JSON 中,我有“kenmerken”部分,我想在其中添加更多项目。我认为这可以通过使用 JSON_MODIFY 来完成。然而,当我使用下面的语句时,它将替换项目 1、2 和 3。当我在 $.kenmerken 之前包含“append”时,它只会显示新的项目。我怎样才能将它们都包含在 kenmerken 对象中?
DECLARE @FirstJSON NVARCHAR(MAX) = N'
{
"message id": "B673A8E4-3652-4544-A02D-BA9726BD71ED",
"volgnummer": 61000233530024,
"debug": null,
"kenmerken": {
"item 1": 1,
"item 2": 1,
"item 3": 1
}
}
';
DECLARE @KenmerkenToAdd NVARCHAR(MAX) = N'
{
"Item 4": false,
"Item 5": false
}
';
SET @FirstJSON = JSON_MODIFY(
@FirstJSON,
' $.kenmerken',
JSON_QUERY(@KenmerkenToAdd)
);
SELECT @FirstJSON;
会给:
{
"message id": "B673A8E4-3652-4544-A02D-BA9726BD71ED",
"volgnummer": 61000233530024,
"debug": null,
"kenmerken": {
"Item 4": false,
"Item 5": false
}
}
我想要的地方:
{
"message id": "B673A8E4-3652-4544-A02D-BA9726BD71ED",
"volgnummer": 61000233530024,
"debug": null,
"kenmerken": {
"Item 1": 1,
"Item 2": 1,
"Item 3": 1,
"Item 4": false,
"Item 5": false
}
}
我一直在挠头,重新阅读MSFT帮助,但我仍然无法理解sys.dm_db_index_operational_stats和sys.dm_db_index_physical_stats中的forwarded_fetch_count和forwarded_record_count之间的区别。让我用下面的例子来说明我理解观点的问题。
我运行了以下查询:
;with heaps as (
select
DB_NAME(DB_ID()) dbname, object_name ( p.object_id ) objname, sum(row_count) row_count,
DB_ID() database_id, p.object_id objectid
from
sys.dm_db_partition_stats p
join sys.objects o on o.object_id = p.object_id
WHERE
index_id = 0 and o.is_ms_shipped = 0 --and row_count > 0
group by p.object_id )
select
h.*,
forwarded_fetch_count
from heaps h
cross apply sys.dm_db_index_operational_stats(database_id, objectid, 0, null) ps
WHERE forwarded_fetch_count > 0 ORDER BY forwarded_fetch_count DESC¨
和
SELECT page_count, OBJECT_NAME(ps.object_id)
,avg_record_size_in_bytes
,avg_page_space_used_in_percent
,forwarded_record_count
FROM sys.dm_db_index_physical_stats(db_id('your_db_name'), NULL,NULL, NULL, 'DETAILED') AS ps
WHERE forwarded_record_count IS NOT NULL AND forwarded_record_count > 0
GO
这两个查询都返回了我正在调整的单个数据库中的不同表列表。第一个查询返回的表中每个表有 1000 到 100 000 条转发提取,第二个查询返回其他表集的 10 - 60 000 条转发记录计数。
作为管道胶带修复,我重建了有问题的表格。然而,在 Windows 的性能监视器中,我仍然看到大量的转发记录/秒(图表通常飙升至 100)。运行 sp_blitzfirst @seconds = 30 时,我会收到每秒大量转发的提取的警报。一旦警报是一般警报(意味着与任何数据库无关),同一语句的其他 9 个警报就会提到:“Forwarded Fetches/Sec High:TempDB Object”。根据转发的提取计数,TempDB 中的转发提取数量比 TempDB 中的转发提取数量多十倍或一百倍。
最后但并非最不重要的一点是,ISV 大量实施了触发器(我将其与 TempDB 转发提取相关)。
我的问题:
- 两个视图中的两列有什么区别?
- 当处理由于堆上转发记录而导致数据库缓慢时,我应该使用哪一个?(我知道MSFT的帮助提到了dm_db_index_physical_stats中与堆相关的forwarded_record_count,但仍然没有让我更清楚)。
- 我可以确定 TempDB 中的什么原因导致这些转发的提取吗?
我有以下问题,我的 TempDB 知识还没有涵盖这一点:
- 在 SSMS 中运行约 200 毫秒的分析查询,从应用程序启动时在 SQL Server 上继续运行 60 秒以上 - 这种情况只是偶尔发生,大多数时候问题并不存在
- 可运行/挂起查询的队列可能会增长到同一查询文本的数十个查询,其中一个 SELECT 查询是阻止其他相同 SELECT 的头阻塞程序
- 当可运行/挂起队列与基线相比开始显着增长时,对于相同文本和参数值的特定查询,最主要的等待是 SOS_SCHEDULER_YIELD 和 PAGELATCH_UP
- 当问题发生时,排队的数十个查询具有相同的文字参数值(轮班开始时间戳、员工 ID 和生产区域)
- 被挂起的查询(在我们的监控快照期间 - DBA Dash)将 PAGELATCH_UP 等待作为最主要的等待,并且它们正在等待 tempdb 中的 GAM 页面
- 当我使用在可运行/挂起队列中不断堆积的查询参数检查 SSMS 中的执行计划时,查询不会溢出到 tempdb
服务器、数据库和数据库流量的配置:
- 4 到 6 个核心(问题独立发生在具有不同核心数的两台不同服务器上)
- 4 - 6 个大小统一的 TempDB 文件
- 分配给实例的 40GB RAM
- 在特定数据库中,启用了 RCSI + 快照(因此 TempDB 受到攻击)
- 运行查询的两个表上没有发生删除,只有 INSERT 和 SELECT - 当时仅插入 1 行
- SELECT 通常会命中最年轻的记录(最近插入的记录)
- 服务器通常每秒处理 400 - 700 个批量请求;当问题出现时,与正常操作相比,它会达到峰值 1500,从而产生较高的 IO + CPU 负载
- 表中的数据或多或少具有均匀分布,即特定生产区域的无班次中没有员工 ID 的记录明显多于其他员工
- 所附屏幕截图是一张表格,显示了问题完全显现时 DBA Dash 的快照
- tempDB,尽管 RCSI+ 快照增长不多,但在 60GB 驱动器上只有几 GB(稳定状态持续了几个月,并且在我在这里描述的几集之后)
- 屏幕截图中的所有 SELECT 查询都有 PAGELATCH_UP 等待,其中大约一半具有以下附加信息:
- 等待资源类型:PAGE
- 等待资源:2:3:2(我认为含义是:tempdb数据库,tempdb中的第三个文件,我们正在等待的第二页)
- 等待文件:主| 温度2
- 页面类型:GAM
- 等待编译:False
除了明显努力找到根本原因并永久解决它之外,我的主要问题是:
- 为什么 SELECT 查询可以大量访问 tempdb 中的 GAM 页面?
- 如果我承认 SELECT 可以频繁接触 GAM 页面,那么什么可以阻止查询(头拦截器)进行(即读取 GAM 页面并使其立即可供其他人使用)?
任何相关学习资源/建议的指针将不胜感激
编辑:为了回答约翰的评论,我想添加以下内容:
- CTFP:30
- MAXDOP:4(为两台 SQL 服务器设置,其中一个有 6 个核心,另一个有 4 个)
- 每个 SQL VM 有 2 个实例 - 发生问题的实例,然后是其他“办公室”实例,这对 SQL Server VM 造成的负载可以忽略不计
- 表格
ManualPanelEntries:6933089 条记录,1221 MB 数据,2591 MB 索引 - 事实上,索引比数据本身消耗更多空间
权重:3108486条记录,178MB数据,170MB索引
- 整个数据库:125GB
===========
写完这篇文章后我发现,头阻止程序(许多并行的相同 SELECT 之一)也在等待 GAM,即特定 tempdb 文件的第二页。就好像其他东西(版本存储?)在特定的 GAM 页面上持有锁定,阻止使用 TempDB 的其他查询继续进行。
我正在运行 IIS 10 的 Windows Server 2019(带 SSD 驱动器)上使用 SQL Server SE 2019。在 IIS 10 之上运行 ASP.Net 应用程序,必须按原样考虑(我无法修改它) 。
最近发现 ASP.Net 应用程序可能变得有点过于啰嗦,并开始批量进行许多数据库查询(很少突发 20-30 个查询/秒)。在重负载下这可能会成为一个问题,所以我想提高系统性能。SQL Server 的安装没有任何特定配置(安装向导的默认配置)。
我想知道是否有一些已知的配置可以调整(SQL Server/IIS),它可以优化以 20-30 个查询/秒的批量发送许多小而快速的查询(每个查询大约 5 毫秒)的场景。这样我就可以改善 ASP.Net 应用程序负载较重的情况,并开始向数据库发送大量快速查询
好的,所以我有一系列 AWS VM,主要使用内置 SQL Server 2019 的z1d.3xlarge服务器类,这些服务器每个都包含一个不同大小的 NVMe。(不足为奇)我将我的 SQL Server TempDB 驱动器放在这个驱动器上,运行良好,没问题。
现在我正在尝试在 Azure 上做完全相同的事情,在这种情况下,我使用的是“标准 E4bds v5”类和 SQL Server 2022 开发许可证,同样的交易,附加的 NVMe,高性能(由“atto”验证对它进行基准测试,它实际上预制得更好),应该工作正常,除了它不......
例如,我有一个查询在任何一台服务器上运行时都会产生大量 TempDB 溢出(在两台服务器上生成相同的查询计划):
蔚蓝
AWS(完全相同的计划)
相同的查询、相同的计划、相同的 tempDB 溢出,在 AWS 服务器上,3 分钟,在 Azure 服务器上,11 分钟。为什么?很好地分配了各种等待统计和 perfmon,当 TempDB 溢出发生在 Azure 服务器上时,它会以每秒 25MB 的速度排序站点:
如果你在 AWS 服务器上运行同样的东西,你会看到高达每秒 900MB 的峰值。看看这个,我相信导致 TempDB 驱动器 IO 性能降低的任何因素也会导致运行时间延长。我研究了以下因素:
CPU:两台服务器上的 CPU 通常都很低,大部分时间低于 10%
内存:这个查询只导致 SQL Server 占用大约 1GB 左右,它使用的内存非常少,服务器上只使用了 12% 的内存,我禁用了分页并启用了锁定内存,没有效果
其他磁盘 IO:一切都是高级 SSD,基准测试很棒,在 Perfmon 中看起来不错,我可以在资源监视器中看到大部分使用都集中在“D”驱动器(tempDB)上:
活动监视器:运行时只显示一堆读取,少量 BufferIO 等待:
这种性能不佳的最可能原因是什么,TempDB 速度的瓶颈是什么(在这种情况下但不是在其他查询中),我将如何确定导致查询速度差异的两台服务器之间的差异?
更新 1
根据 JD 的要求,我已在每台服务器上的 TempDB 驱动器的 CrystalMark 基准测试下方发布
AWS 临时驱动器性能:
Azure 临时驱动器性能:
出于某种原因,该基准测试显示 Azure 驱动器的性能比 AWS 驱动器的性能差(这与显示相反结果的 ATTO 基准测试结果不同)。也许这就是正在发生的事情,到目前为止我一直专注于“ Ebsv5 系列”,我将尝试获得更大的服务器,理论上应该在所有驱动器上为我提供更多的“IOPS/MBps”(不是确定这是否会影响 NVMe 的...)。
我还将对更大的服务器进行基准测试,看看它的性能是否更好,我将在此处发布结果。
更新 2
是的,JD 是对的,“Standard_E16-8ads_v5”更好看:
我正在尝试解决我的两个环境中的一些谜团。两者都是 SQL 2019 部署,但是一个配置了 Kerberos(即为实例和端口注册了 SPN),而另一个部署没有。我一直在尝试调查这是如何发生的,但还没有深入了解。
基本上,我想了解未来部署的要求。我应该手动创建(或请求创建)SPN 还是有一些方法可以自动创建它们?例如,它们是否可以在构建应用程序层的过程中创建?
如果有人能帮我解释一下,我将不胜感激。当然,我一直在研究有关 Kerberos 身份验证和 SPN 的所有内容,但如果有关于此特定问题的任何特定文章,我将不胜感激,请提供指向它的链接。
谢谢
我想选择某些对象的所有点击和查看。点击次数和查看次数在单独的表中进行跟踪,但我希望为包含查看次数和点击次数的对象返回 1 行。这适用于以下 SQL:
SELECT * FROM (
SELECT distinct(title)
,ROW_NUMBER() OVER (ORDER BY id ASC) AS RowNum
,SUM(vws) as vws,SUM(clicks) as clicks,id FROM(
SELECT l.id,l.title,0 as vws, COUNT(lc.id) as clicks
FROM locs l
INNER JOIN locs_clicks lc on l.id=lc.locid
GROUP BY l.title,l.id
UNION
SELECT l.id,l.title,COUNT(lv.id) as vws,0 as clicks
FROM locs l
INNER JOIN locs_views lv on l.id=lv.locid
GROUP BY l.title,l.id
)t
GROUP BY title,id
) as info
WHERE RowNum > 0 AND RowNum <= 100
我得到如下结果:
title RowNum vws clicks id
Mercedes Benz 12697 43 2 17231289
但是,当我想对视图 ( vws
) 进行排序并更改 1 行时:
`,ROW_NUMBER() OVER (ORDER BY vws ASC) AS RowNum`
我收到错误:
列“t.vws”在选择列表中无效,因为它未包含在聚合函数或 GROUP BY 子句中。
但是然后当我更改为GROUP BY title,id,vws
结束此查询时:
SELECT * FROM (
SELECT distinct(title)
,ROW_NUMBER() OVER (ORDER BY vws ASC) AS RowNum
,sum(vws) as vws,sum(clicks) as clicks,id FROM(
SELECT l.id,l.title,0 as vws, COUNT(lc.id) as clicks
FROM locs l
INNER JOIN locs_clicks lc on l.id=lc.objectid
GROUP BY l.title,l.id
UNION
SELECT l.id,l.title,COUNT(lv.id) as vws,0 as clicks
FROM locs l
INNER JOIN locs_views lv on l.id=lv.objectid
GROUP BY l.title,l.id
)t
GROUP BY title,id,vws
) as info
WHERE RowNum > 0 AND RowNum <= 100
这些行不再按不同的标题汇总为 1 行:
title RowNum vws clicks id
Mercedes Benz 699 0 2 17231289
Mercedes Benz 18102 43 0 17231289
如何选择唯一行title
并返回相同clicks
的vws
结果/行?
昨天下午晚些时候,我将 4 个 tempdb 数据文件添加到现有的 4 个中,总共 8 个(SQL 服务器上的 16 个处理器)。我还预先将它们种植到接近 100% 的可用空间。
今天,我们的一位开发人员联系了我,她说昨天她正在运行一个查询,该查询将在 3-5 秒内将一组初始结果返回到 ssms 显示,整个查询将在 2-3 分钟内完成。今天查询需要 5 分钟才能完成,大约 2.5 分钟内没有结果显示在 ssms 中。
当时没有其他查询在运行。CPU 使用率很低。我反弹了服务器,没有任何改善。所以现在我想知道我的 tempdb 更改是否导致性能下降。我看不出如何,但偏执狂开始了。我运行了查询并在它执行时监视了 tempdb,它似乎根本没有使用 tempdb,我觉得这很奇怪,因为它有一个我认为使用的 GROUP BY 语句临时数据库。该表包含大约 2200 万行,查询返回大约 780 万行。
select
DATEADD(q, DATEDIFF(q, 0, MonthOfDate), 0) as Quarter
,[PartnerCD]
,[PartnerNM]
,[PartnerGRP]
,[BizMemberID]
,[MemberID]
,[BizType]
,[RateCD]
,[Rate]
,sum([MemberMonth]) as MemberQuarter
,[CurrentAge]
,[AgeAtTime] = CASE WHEN dbo.fn_CalculateAge(BirthDT, (DATEADD(q, DATEDIFF(q, 0, MonthOfDate), 0)), 'YEAR') < 0 THEN NULL ELSE dbo.fn_CalculateAge(BirthDT, (DATEADD(q, DATEDIFF(q, 0, MonthOfDate), 0)), 'YEAR') END
,AgeCategory = dbo.fn_CalculateAgeCatYrsOrdered(BirthDT, (DATEADD(q, DATEDIFF(q, 0, MonthOfDate), 0)))
,[BirthDT]
,[ZipCD]
FROM [Partner].[dbo].[Membership]
group by DATEADD(q, DATEDIFF(q, 0, MonthOfDate), 0)
,[PartnerCD]
,[PartnerNM]
,[PartnerGRP]
,[BizMemberID]
,[MemberID]
,[BizType]
,[RateCD]
,[Rate]
,[CurrentAge]
,[BirthDT]
,[ZipCD]
可能是我的更改导致性能下降还是巧合?
我正在构建一个简单的工作板(使用 MS SQL/ASP.NET core/C#)并且对数据库设计有疑问。我不知道在某些情况下如何决定是否应该创建一个单独的表。
我有下表:
- 工作
- 类别
- 行业
- 地区
在 Job 表中,我将薪水存储在“Salary”字段中,但我还需要存储“SalaryPeriod”,即支付薪水的频率:每年、每月、每周、每天或每小时。
1) 创建一个包含 5 个选项(每年、每月等)的 SalaryPeriod 表更好,还是 2) 将工资期作为字符串存储在 Job 表中更好?
我倾向于#1,因为:
- 维护数据更容易,例如,如果我需要编辑或添加工资类型(老实说,我不认为我会修改选项,但你永远不会知道)
- 我没有性能问题