我们的开发人员(在我成为 DBA 之前)将字段的数据类型设置为VARCHAR(MAX)
实际上只需要VARCHAR(255)
. 直到我们的表增长到超过几百万条记录和近 TB 的数据之后,才发现这一点。当我在该表上进入设计模式以在我们的测试环境中测试此更改时,我发现它创建的脚本会生成表的 _tmp 表副本,然后删除原始表并将 _tmp 重命名为原始表。我似乎记得学习这背后的原因与必须将数据从记录的“LOB”部分移动到记录的固定长度部分有关(或者我的记忆回忆起来)。但是,我找不到任何关于为什么会发生这种情况的文档(而不仅仅是更改大小)。有人可以指出我正确的方向,以便我可以更好地向管理层解释为什么现在在数百万个记录表上进行此更改将需要很长时间。
Chris Woods's questions
我有一个查询,其中包含多个性能不佳的联接。经过大量分类后,我决定拆开查询,只看驱动表。以下是仅基于驱动表的查询示例。
DECLARE @VAR AS INT
SET @VAR = 11652862
SELECT Field1, Field2
FROM tablea
WHERE Field2 = @VAR
当我按原样运行代码时,实际执行计划会返回 15k 估计行和 1m 实际行。是的,这只是一个简单的SELECT...FROM TABLE
,但请记住,这只是更大查询的一部分,因此随着我们添加更多连接,这种估计差异会大大增加。
我知道问题是@VAR
因为优化器在将查询编译成计划时不知道变量的值,所以它返回字段估计的平均行数。如果我添加OPTION (RECOMPILE)
它将在编译时强制输入值并返回正确的行数。
关键是:这不是我公司可以编辑的自定义代码。它是我无法编辑的第三方应用程序的一部分。更新统计数据无济于事(我查看了直方图,它正确地列出了我的变量的值)。我已经有了这两个领域的覆盖 NC 索引。我能想到的唯一选择是对该查询使用强制执行计划。不过,我从来没有能够成功地做到这一点。有人对强制执行计划有任何其他想法或很好的操作方法参考吗?
由于在评论中被问到,索引的创建语句是:
CREATE NONCLUSTERED INDEX idx ON tablea (Field2)
我们正在执行第 3 方数据的迁移,但它已挂起。
当我们调查时,我们看到 SPID 38(系统/后台 SPID)是试图进行迁移的阻止用户 SPID。不幸的是,来自sp_whoisactive(或什至活动监视器)的 SQL_Text 对于 SPID 38是NULL。wait_info是PREEMPTIVE_OS_GENERICOPS
.
有没有办法告诉 38 试图做什么?
它使用的是第 3 方提供给我们的基于 Windows 的工具。我对数据进行了备份,并将其还原到这台新服务器上(这样数据库及其内容就可以访问并正常工作了)。然后我们运行这个工具来升级到他们的新版本软件,这就是我们获取块的地方。
sp_WhoIsActive @get_locks = 1
返回一个非常长的 XML(4k 个字符太长而无法发布)。
我正在使用 Ola 的脚本进行统计更新,对于一个特定的索引,我想在更新统计时进行全面扫描(以解决升序键问题以及跟踪标志 2389)。我们有成千上万个相同的数据库(这就是我们的供应商软件的工作方式),我想确保该索引的所有统计数据实际上都是在进行全面扫描,而不是抽样。我如何着手运行查询来检查所有数据库?
我可以使用DBCC SHOW_STATISTICS()
, 但它会返回三个结果集——是否可以只将第一个结果集放入表中而忽略其他两个?有更好的选择吗?
我的印象是,如果我DATALENGTH()
将表中所有记录的所有字段相加,我将得到表的总大小。我弄错了吗?
SELECT
SUM(DATALENGTH(Field1)) +
SUM(DATALENGTH(Field2)) +
SUM(DATALENGTH(Field3)) TotalSizeInBytes
FROM SomeTable
WHERE X, Y, and Z are true
我在下面使用了这个查询(我从网上获取表大小,仅聚集索引,因此它不包括 NC 索引)来获取我的数据库中特定表的大小。出于计费目的(我们按部门使用的空间量向部门收费),我需要计算出此表中每个部门使用了多少空间。我有一个查询来标识表中的每个组。我只需要弄清楚每个组占用了多少空间。
由于表中的字段,每行的空间可能会大幅波动VARCHAR(MAX)
,所以我不能只取平均大小 * 部门的行数。当我使用上述DATALENGTH()
方法时,我只得到下面查询中使用的总空间的 85%。想法?
SELECT
s.Name AS SchemaName,
t.NAME AS TableName,
p.rows AS RowCounts,
(SUM(a.total_pages) * 8)/1024 AS TotalSpaceMB,
(SUM(a.used_pages) * 8)/1024 AS UsedSpaceMB,
((SUM(a.total_pages) - SUM(a.used_pages)) * 8)/1024 AS UnusedSpaceMB
FROM
sys.tables t with (nolock)
INNER JOIN
sys.schemas s with (nolock) ON s.schema_id = t.schema_id
INNER JOIN
sys.indexes i with (nolock) ON t.OBJECT_ID = i.object_id
INNER JOIN
sys.partitions p with (nolock) ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id
INNER JOIN
sys.allocation_units a with (nolock) ON p.partition_id = a.container_id
WHERE
t.is_ms_shipped = 0
AND i.OBJECT_ID > 255
AND i.type_desc = 'Clustered'
GROUP BY
t.Name, s.Name, p.Rows
ORDER BY
TotalSpaceMB desc
有人建议我为每个部门创建一个过滤索引或对表进行分区,这样我就可以直接查询每个索引使用的空间。可以通过编程方式创建过滤索引(并在维护窗口期间或当我需要执行定期计费时再次删除),而不是一直使用空间(在这方面分区会更好)。
我喜欢这个建议,并且通常会这样做。但老实说,我以“每个部门”为例来解释我为什么需要这个,但老实说,这并不是真正的原因。由于保密原因,我无法解释我需要这些数据的确切原因,但它类似于不同的部门。
关于这张表上的非聚集索引:如果我能得到 NC 索引的大小,那就太好了。但是,NC 索引占聚集索引大小的比例不到 1%,因此我们可以不包括这些索引。但是,无论如何我们将如何包含 NC 索引?我什至无法获得聚集索引的准确大小:)
当我运行以下代码时,它需要 22.5 分钟并进行 1.06 亿次读取。但是,如果我只运行内部 select 语句,它只需要 15 秒并进行 264k 读取。作为旁注,选择查询不返回任何记录。
知道为什么它IF EXISTS
会使其运行时间更长并进行更多读取吗?我还将 select 语句更改为 doSELECT TOP 1 [dlc].[id]
并在 2 分钟后将其杀死。
作为临时修复,我已将其更改为进行计数(*)并将该值分配给变量@cnt
。然后它会做一个IF 0 <> @cnt
声明。但我认为EXISTS
会更好,因为如果在 select 语句中返回了记录,一旦找到至少一条记录,它将停止执行扫描/搜索,而count(*)
将完成完整的查询。我错过了什么?
IF EXISTS
(SELECT [dlc].[ID]
FROM TableDLC [dlc]
JOIN TableD [d]
ON [d].[ID] = [dlc].[ID]
JOIN TableC [c]
ON [c].[ID] = [d].[ID2]
WHERE [c].[Name] <> [dlc].[Name])
BEGIN
<do something>
END
我有一台具有 16 个 CPU 的服务器,其配置max degree of parallelism
为 8,max worker threads
设置为 0。
在给定的一个小时内,我的信号等待时间为 20%,但在此期间我的操作系统 CPU 利用率从未超过 25%。有人可以解释为什么我的信号等待时间如此之高吗?
我的供应商拥有一流的评分系统,预计我们的信号等待时间为 10% 或更少,否则我们就会被淘汰。我该如何解决这个问题(不添加额外的 CPU)?
- 每个 NUMA 节点的 CPU 不超过 8 个,因此跟踪标志 8048不适用。
- 最大的实例等待是
CXPACKET
(70%),然后是PREEMPTIVE_OS_PIPEOPS
(20%) cost threshold for parallelism
设置为 50。我应该提高它吗?到什么?- 这是一台物理机(不是 VM),专用于 SQL Server。
- 我正在使用监控工具来识别最常运行的查询和过程。我想查看高 CPU、高 I/O 还是高持续时间?通常我们的应用程序是 I/O 密集型的,所以我调整高 I/O。但既然问题是信号等待,我需要看看高 CPU 吗?
- 我希望避免Max Vernon的建议降低
MAXDOP
到 4,因为该应用程序执行一些需要额外线程的仓库样式查询。
我们有每 15 分钟运行一次的日志备份和每晚的完整/差异(每个数据库每周一次完整,但它们分布在整个星期以实现负载平衡)。假设对于一个特定的数据库,我有一个从晚上 10:05 开始到晚上 10:18 结束的差异,我在晚上 10:00、晚上 10:15 和晚上 10:30 有日志备份。如果我想恢复到那天晚上 10:24pm,我知道我需要恢复那天晚上的最后一个完整日志和差异日志,但是我不确定在那之后我应该从哪个事务日志开始。
如果这不是问这个问题的正确地点,我深表歉意,但有些事情困扰着我。我本可以发誓,在以前的工作中,我可以在 SSMS 的最后一行代码上点击向下箭头,然后光标将移动到该行的末尾。现在它只是停留在最后一行的中间。我正在使用 SSMS 11.0.2100.60。是否有我遗漏的设置,或者我是否想象过会发生这种情况?:)
我知道我可以使用 SQL Server 配置管理器来确定 1) 当前正在运行哪些服务以及 2) 哪些服务设置为自动启动。但是,我管理着几十台服务器。我想每季度进行一次检查,以确保所有服务仍设置为自动启动,并查看当前有哪些服务正在运行。是否有表格或程序可以提供此信息?
我之前问过类似的问题,但之前我曾问过关于将备份移动到共享位置的问题。这一次我很好奇:如果我想在共享驱动器上恢复数据库,我需要在该服务器上启用 IFI 还是仅在运行 SQL Server 的服务器上启用?
我问的原因是我正在恢复一个相当大的数据库,并且它在过去几个小时内一直停留在 100% 恢复状态。输入的等待类型sp_whoisactive
是:
(28472716ms) `PREEMPTIVE_OS_WRITEFILEGATHER.
我见过的唯一一次是 IFI 未打开时,但我确实在 SQL Server 上启用了它,但在共享驱动器服务器上未启用它。
我在 SQL 2014 Standard 上做离线 DBCC CHECKDBs(等等在生产以外的盒子上)。在大多数情况下,我的过程进展得很快,但由于某种原因,我有这个小数据库(6gbs),而且它需要几个小时来完成 DBCC。上次运行它花了 9 个小时。检查 sys.dm_exec_requests 时,它似乎在不同的 % 完成时冻结。在同一台服务器上,我在 TB 范围内的数据库上执行 CHECKDB 没有问题。我现在在 CHECKDB 中使用以下提示(是的,最终我会做完整的而不是只做物理)
WITH NO_INFOMSGS, ALL_ERRORMSGS, PHYSICAL_ONLY, TABLOCK
这个数据库可能会导致它永远花费什么?
我知道在 SQL Server 上启用 IFI(即时文件初始化)很好。备份存档位置如何?我们将我们的数据库备份到本地 SSD 驱动器(因此备份速度很快),然后一整天我们慢慢地将备份移动到存档位置,并在非生产服务器上执行恢复和 DBCC。我很好奇我们将备份复制到的存档位置是否应该启用 IFI?
我刚刚继承了一组新服务器,而设置它们的人将“登录为”帐户作为默认的“NT Service\MSSQLSERVER”。我想将其更改为 Active Directory 服务名称。在我们已经投入生产之后,我从未尝试过更改它。有什么我应该注意的吗?是否需要重新启动服务?此服务器仅使用 SQL,而不使用 SSIS、SSAS、SSRS。我将确保 AD 服务名称可以访问访问文件所需的所有文件夹。还有什么我想念的吗?
我们正在离线服务器上设置离线 DBCC checkdbs,这样我们仍然可以进行检查,但不会干扰生产。
当我们备份主数据库并恢复它(甚至直接在同一生产机器上的本地 SSD 上)时,当我们 DBCC CHECKDB 恢复的数据库(master_restore)时,我们会得到 36 个损坏错误。
但是当我 DBCC CHECKDB 原来的主数据库时,我没有得到任何错误。任何想法?
Check Catalog Msg 3851, State 1: An invalid row (class=12,depid=0,depsubid=0) was found in the system table sys.syssingleobjrefs (class=12).
Check Catalog Msg 3851, State 1: An invalid row (class=13,depid=1,depsubid=0) was found in the system table sys.syssingleobjrefs (class=13).
Check Catalog Msg 3851, State 1: An invalid row (class=60,depid=1,depsubid=0) was found in the system table sys.syssingleobjrefs (class=60).
Check Catalog Msg 3851, State 1: An invalid row (class=26,depid=1,depsubid=0,indepid=3,indepsubid=0) was found in the system table sys.sysmultiobjrefs (class=26).
Check Catalog Msg 3851, State 1: An invalid row (class=13,depid=2,depsubid=0) was found in the system table sys.syssingleobjrefs (class=13).
Check Catalog Msg 3851, State 1: An invalid row (class=60,depid=2,depsubid=0) was found in the system table sys.syssingleobjrefs (class=60).
Check Catalog Msg 3851, State 1: An invalid row (class=60,depid=3,depsubid=0) was found in the system table sys.syssingleobjrefs (class=60).
Check Catalog Msg 3851, State 1: An invalid row (class=60,depid=4,depsubid=0) was found in the system table sys.syssingleobjrefs (class=60).
Check Catalog Msg 3851, State 1: An invalid row (class=60,depid=5,depsubid=0) was found in the system table sys.syssingleobjrefs (class=60).
Check Catalog Msg 3851, State 1: An invalid row (class=26,depid=261,depsubid=0,indepid=3,indepsubid=0) was found in the system table sys.sysmultiobjrefs (class=26).
Check Catalog Msg 3851, State 1: An invalid row (class=26,depid=262,depsubid=0,indepid=3,indepsubid=0) was found in the system table sys.sysmultiobjrefs (class=26).
Check Catalog Msg 3851, State 1: An invalid row (class=26,depid=263,depsubid=0,indepid=3,indepsubid=0) was found in the system table sys.sysmultiobjrefs (class=26).
Check Catalog Msg 3851, State 1: An invalid row (class=26,depid=264,depsubid=0,indepid=3,indepsubid=0) was found in the system table sys.sysmultiobjrefs (class=26).
Check Catalog Msg 3851, State 1: An invalid row (class=26,depid=266,depsubid=0,indepid=3,indepsubid=0) was found in the system table sys.sysmultiobjrefs (class=26).
Check Catalog Msg 3851, State 1: An invalid row (class=26,depid=268,depsubid=0,indepid=3,indepsubid=0) was found in the system table sys.sysmultiobjrefs (class=26).
Check Catalog Msg 3851, State 1: An invalid row (class=26,depid=269,depsubid=0,indepid=9,indepsubid=0) was found in the system table sys.sysmultiobjrefs (class=26).
Check Catalog Msg 3851, State 1: An invalid row (class=26,depid=269,depsubid=0,indepid=10,indepsubid=0) was found in the system table sys.sysmultiobjrefs (class=26).
Check Catalog Msg 3851, State 1: An invalid row (class=26,depid=273,depsubid=0,indepid=3,indepsubid=0) was found in the system table sys.sysmultiobjrefs (class=26).
Check Catalog Msg 3851, State 1: An invalid row (class=26,depid=274,depsubid=0,indepid=3,indepsubid=0) was found in the system table sys.sysmultiobjrefs (class=26).
Check Catalog Msg 3851, State 1: An invalid row (class=26,depid=277,depsubid=0,indepid=3,indepsubid=0) was found in the system table sys.sysmultiobjrefs (class=26).
Check Catalog Msg 3851, State 1: An invalid row (class=26,depid=278,depsubid=0,indepid=3,indepsubid=0) was found in the system table sys.sysmultiobjrefs (class=26).
Check Catalog Msg 3851, State 1: An invalid row (class=26,depid=279,depsubid=0,indepid=3,indepsubid=0) was found in the system table sys.sysmultiobjrefs (class=26).
Check Catalog Msg 3851, State 1: An invalid row (class=26,depid=280,depsubid=0,indepid=3,indepsubid=0) was found in the system table sys.sysmultiobjrefs (class=26).
Check Catalog Msg 3851, State 1: An invalid row (class=26,depid=283,depsubid=0,indepid=3,indepsubid=0) was found in the system table sys.sysmultiobjrefs (class=26).
Check Catalog Msg 3851, State 1: An invalid row (class=76,depid=65536,depsubid=101) was found in the system table sys.syssingleobjrefs (class=76).
Check Catalog Msg 3851, State 1: An invalid row (class=76,depid=65536,depsubid=103) was found in the system table sys.syssingleobjrefs (class=76).
Check Catalog Msg 3851, State 1: An invalid row (class=76,depid=65536,depsubid=104) was found in the system table sys.syssingleobjrefs (class=76).
Check Catalog Msg 3851, State 1: An invalid row (class=76,depid=65536,depsubid=105) was found in the system table sys.syssingleobjrefs (class=76).
Check Catalog Msg 3851, State 1: An invalid row (class=76,depid=65536,depsubid=107) was found in the system table sys.syssingleobjrefs (class=76).
Check Catalog Msg 3851, State 1: An invalid row (class=76,depid=65537,depsubid=101) was found in the system table sys.syssingleobjrefs (class=76).
Check Catalog Msg 3851, State 1: An invalid row (class=76,depid=65537,depsubid=103) was found in the system table sys.syssingleobjrefs (class=76).
Check Catalog Msg 3851, State 1: An invalid row (class=76,depid=65537,depsubid=107) was found in the system table sys.syssingleobjrefs (class=76).
CHECKDB found 0 allocation errors and 32 consistency errors not associated with any single object.
Page (1:10) in database ID 13 is allocated in the SGAM (1:3) and PFS (1:1), but was not allocated in any IAM. PFS flags 'MIXED_EXT ALLOCATED 0_PCT_FULL'.
CHECKDB found 1 allocation errors and 0 consistency errors in table '(Object ID 99)' (object ID 99).
CHECKDB found 1 allocation errors and 32 consistency errors in database 'master_restore'
我们最近与一家新公司合并,他们的服务器上有 265 个数据库(6.6tb 的 mdfs)。在我们合并后不久,另一个 DBA 说需要 60 分钟才能关闭我认为非常高的服务。昨晚他们停下来开始服务,果然花了60分钟。今天早上看日志,发现sql日志文件在尝试停止服务的过程中出现如下错误信息。
我知道如果你有很多 VLF,SQL 需要更长的时间来启动备份,但是从它启动到恢复完成消息出现在日志中只需要 1 分钟。知道60分钟是否正常吗?或者如果没有,我该怎么做才能加快速度。谢谢!
Error: 17142, Severity: 14, State: 0.
SQL Server service has been paused. No new connections will be allowed. To resume the
service, use SQL Computer Manager or the Services application in Control Panel.
Error: 18456, Severity: 14, State: 13.
Login failed for user ''. Reason: SQL Server service is paused.
No new connections can be accepted at this time. [CLIENT: xx.xxx.xx.xx]