小编Jos*_*ell的帖子

在 SQL Server 中查找新跟踪标志的方法

那里有很多跟踪标志。有些有据可查,有些没有,还有一些在 2016 版本中找到了默认行为状态的方法。除了官方支持渠道、微软员工等,还有什么方法可以找到新的跟踪标志?

我已经在这里这里阅读了 Aaron Bertrand 最近的几篇文章,但没有发现任何关于新跟踪标志的信息。

我将 mssqlsystemresource 的数据和日志文件复制到一个新位置,并像常规数据库一样附加它以浏览系统表和视图,但没有立即发现任何内容。我考虑过列出已知跟踪标志的列表,并循环遍历不在该列表中的数字,以查看 DBCC TRACEON 允许哪些,但想先在这里提出问题。

假设启用它们的 DBCC 命令必须检查某些资源以确保跟踪标志有效,那么它会到达哪里?是否有包含列表的 .dll 或其他系统文件?

我知道这个问题撒了一个广泛的网络,但促使它阅读的原因是阅读了具有特定预期行为的 Trace Flag 以及 2016 年没有产生所描述效果的新功能。我最初的想法是,也许数字以某种方式转置了,比如 7129 变成了 7219。我希望得到一个范围内的有效跟踪标志列表,比如 7000-7999,以寻找排列。将它们全部作为 DBCC TRACEON 标志和启动参数进行测试,再加上针对功能行为测试结果,将会非常麻烦。

sql-server trace-flags

39
推荐指数
3
解决办法
1738
查看次数

截断 AG 中包含 170 亿行的表

我需要截断一个包含 170 亿行的表,该表位于作为 AG 一部分的数据库中。

此操作对 AG 延迟和日志备份大小有什么影响?

有推荐的方法吗?

sql-server truncate transaction-log availability-groups

20
推荐指数
2
解决办法
3269
查看次数

为什么 CHECKDB 读取具有内存优化表的数据库上的事务日志文件?

tl; dr:为什么 CHECKDB 读取具有内存优化表的用户数据库的事务日志?


CHECKDB 在检查我的一个数据库时似乎正在读取用户数据库的事务日志文件 - 特别是使用内存中 OLTP 表的数据库。

这个数据库的 CHECKDB 仍然在合理的时间内完成,所以我主要只是对这种行为感到好奇;但这绝对是该实例上所有数据库中 CHECKDB 持续时间最长的。

在查看 Paul Randal 的史诗“ CHECKDB From Every Angle:所有 CHECKDB 阶段的完整描述”时,我看到 SQL 2005 之前的 CHECKDB用于读取日志以获得一致的数据库视图。但由于这是 2016 年,它使用内部数据库快照。

但是,快照先决条件之一是:

源数据库不得包含 MEMORY_OPTIMIZED_DATA 文件组

我的用户数据库有这些文件组之一,所以看起来快照不在表中。

根据CHECKDB 文档

如果无法创建快照,或者指定了 TABLOCK,DBCC CHECKDB 将获取锁以获得所需的一致性。在这种情况下,需要一个排他数据库锁来执行分配检查,并且需要共享表锁来执行表检查。

好的,所以我们正在做数据库和表锁定而不是快照。但这仍然不能解释为什么它必须读取事务日志。那么什么给呢?

我在下面提供了一个脚本来重现该场景。它用于sys.dm_io_virtual_file_stats识别日志文件读取。

请注意,大多数时候它读取日志的一小部分 (480 KB),但偶尔读取更多 (48.2 MB)。在我的生产场景中,当我们运行 CHECKDB 时,它会在每晚午夜读取大部分日志文件(2 GB 文件中的约 1.3 GB)。

以下是我目前使用脚本获得的输出示例:

collection_time            num_of_reads     num_of_bytes_read
2018-04-04 15:12:29.203    106              50545664
Run Code Online (Sandbox Code Playgroud)

或这个:

collection_time            num_of_reads     num_of_bytes_read …
Run Code Online (Sandbox Code Playgroud)

sql-server transaction-log dbcc-checkdb sql-server-2016

16
推荐指数
1
解决办法
815
查看次数

当 SQL Server 没有可用的物理内存时会发生什么?

在谷歌搜索时,我发现了一些相互矛盾的信息。

某些站点指出,当没有为数据留下物理内存时,SQL Server 会将现有数据移动到 TEMPDB(请参阅:SQL Server:揭秘 TempDb 和建议)。

但是其他站点声明,当没有足够的物理内存时,操作系统可以使用 PAGE FILE 并将数据从物理内存移到它(请参阅SQL Server 的页面文件)。

我想知道当 SQL Server 物理内存不足时,它会在哪里写入数据?到 tempdb 还是到 OS Page 文件?或者两者都有?

sql-server data-pages memory tempdb sql-server-2014

16
推荐指数
1
解决办法
2767
查看次数

尝试回收未使用的空间会导致 SQL Server 中的已用空间显着增加

我在生产数据库中有一个表,其大小为 525 GB,其中 383 GB 未使用:

未使用的空间

我想回收其中的一些空间,但是,在弄乱生产数据库之前,我正在测试数据库中数据较少的相同表上测试一些策略。这个表有一个类似的问题:

未使用的空间

关于表的一些信息:

  • 填充因子设置为 0
  • 大约有 30 列
  • 其中一列是图像类型的 LOB,它存储的文件大小从几 KB 到几百 MB
  • 该表没有任何与之关联的假设索引

服务器正在运行 SQL Server 2017 (RTM-GDR) (KB4505224) - 14.0.2027.2 (X64)。数据库正在使用SIMPLE恢复模型。

我尝试过的一些事情:

  • 重建索引:ALTER INDEX ALL ON dbo.MyTable REBUILD. 这产生了微不足道的影响。
  • 重新组织索引:ALTER INDEX ALL ON dbo.MyTable REORGANIZE WITH(LOB_COMPACTION = ON). 这产生了微不足道的影响。
  • 将 LOB 列复制到另一个表,删除该列,重新创建该列,并将数据复制回来(如这篇文章所述:释放未使用的空间 SQL Server 表)。这减少了未使用的空间,但似乎只是将其转换为已用空间:

    未使用的空间

  • 使用 bcp 实用程序导出表、截断它并重新加载它(如这篇文章所述:如何为表释放未使用的空间)。这也减少了未使用的空间并增加了与上图类似的程度。

  • 即使不推荐,我也尝试了 DBCC SHRINKFILE 和 DBCC SHRINKDATABASE 命令,但它们对未使用的空间没有任何影响。
  • 跑步DBCC CLEANTABLE('myDB', 'dbo.myTable')没什么区别
  • 在保持图像和文本数据类型以及将数据类型更改为 varbinary(max) 和 …

index sql-server storage sql-server-2017

15
推荐指数
1
解决办法
1288
查看次数

直方图外的基数估计

设置

我在理解基数估计时遇到了一些麻烦。这是我的测试设置:

  • Stack Overflow 数据库 2010 版
  • SQL Server 2017 CU15+GDR (KB4505225) - 14.0.3192.2
  • 新 CE(兼容级别 140)

我有这个过程:

USE StackOverflow2010;
GO

CREATE OR ALTER PROCEDURE #sp_PostsByCommentCount
    @CommentCount int
AS
BEGIN
    SELECT * 
    FROM dbo.Posts p
    WHERE 
        p.CommentCount = @CommentCount
    OPTION (RECOMPILE); 
END;
GO
Run Code Online (Sandbox Code Playgroud)

dbo.Posts表上没有非聚集索引或统计信息(在 上有聚集索引Id)。

当为此要求估计计划时,“估计行数”dbo.Posts是 1,934.99:

EXEC #sp_PostsByCommentCount @CommentCount = 51;
Run Code Online (Sandbox Code Playgroud)

当我询问估计计划时,自动创建了以下统计对象:

DBCC SHOW_STATISTICS('dbo.Posts', [_WA_Sys_00000006_0519C6AF]);
Run Code Online (Sandbox Code Playgroud)

SSMS 中统计输出的屏幕截图

其中的亮点是:

  • 统计数据的采样率非常低,为 1.81% (67,796 / 3,744,192)
  • 仅使用了 31 个直方图步骤
  • “所有密度”值为0.03030303(采样了 33 个不同的值)
  • RANGE_HI_KEY直方图中的最后一个是 50,其中EQ_ROWS1 …

sql-server statistics database-internals cardinality-estimates sql-server-2017

15
推荐指数
1
解决办法
471
查看次数

SQL Server 2017(包括旧版本)是否支持 8k 磁盘扇区大小?

磁盘(松散的措辞不仅包括旋转媒体,还包括非旋转媒体 [SSD、NVMe 等])驱动器在其底层格式和硬件方面不断发展。其中一部分是从 512 字节物理扇区大小到 4k 物理扇区大小的“增强”,这改变了磁盘布局(512n、512e、4kn)。

下一个演变是使用 8k 物理扇区大小,一些制造商开始生产并在生产中设置。鉴于下一步,Windows 是否支持 8k 扇区大小的磁盘?SQL Server 是否关心扇区大小?

sql-server hardware

14
推荐指数
1
解决办法
893
查看次数

为什么这个流聚合是必要的?

看看这个查询。它非常简单(有关表和索引定义以及重现脚本,请参见文章末尾):

SELECT MAX(Revision)
FROM dbo.TheOneders
WHERE Id = 1 AND 1 = (SELECT 1);
Run Code Online (Sandbox Code Playgroud)

注意:“AND 1 = (SELECT 1) 只是为了防止此查询被自动参数化,我觉得这使问题变得混乱 - 尽管有或没有该子句,它实际上获得了相同的计划

这是计划(粘贴计划链接)

使用流 agg 进行计划

由于那里有一个“top 1”,我很惊讶地看到流聚合运算符。对我来说似乎没有必要,因为保证只有一行。

为了测试这个理论,我尝试了这个逻辑上等效的查询:

SELECT MAX(Revision)
FROM dbo.TheOneders
WHERE Id = 1
GROUP BY Id;
Run Code Online (Sandbox Code Playgroud)

这是那个计划(粘贴计划链接):

没有流 agg 的计划

果然,group by 计划能够在没有流聚合操作符的情况下通过。

请注意,两个查询都从索引的末尾“向后”读取并执行“前 1”以获得最大修订。

我在这里缺少什么? 流聚合是否在第一个查询中真正起作用,还是应该能够消除它(这只是优化器的一个限制,它不是)?

顺便说一下,我意识到这不是一个非常实际的问题(两个查询都报告 0 毫秒的 CPU 和经过时间),我只是对这里展示的内部/行为感到好奇。


这是我在运行上述两个查询之前运行的设置代码:

DROP TABLE IF EXISTS dbo.TheOneders;
GO

CREATE TABLE dbo.TheOneders
(
    Id INT NOT NULL,
    Revision SMALLINT NOT NULL,
    Something NVARCHAR(23),

    CONSTRAINT PK_TheOneders PRIMARY KEY NONCLUSTERED …
Run Code Online (Sandbox Code Playgroud)

sql-server aggregate database-internals group-by sql-server-2017

12
推荐指数
1
解决办法
691
查看次数

用于死锁检测的 SQL 扩展事件会话

有没有办法增加<inputbuf>死锁扩展事件会话捕获的死锁 XML 中元素的大小?

我们希望查看完整的查询以帮助查明应用程序代码中的问题。

似乎仅限于 1024 个字符 +/-。可以增加吗?

请参阅下面的示例 XML。可以看到<inputbuf>元素中的查询文本在选择列表的中间被截断了:

<deadlock>
 <victim-list>
  <victimProcess id="processc9c0829848" />
 </victim-list>
 <process-list>
  <process id="processc9c0829848" taskpriority="0" logused="0" waitresource="PAGE: 5:1:40600276 " waittime="696" ownerId="255115931225" transactionname="SELECT" lasttranstarted="2019-04-24T09:29:25.950" XDES="0xc8dfa8da40" lockMode="S" schedulerid="13" kpid="8480" status="suspended" spid="245" sbid="2" ecid="0" priority="0" trancount="0" lastbatchstarted="2019-04-24T09:29:25.950" lastbatchcompleted="2019-04-24T09:29:25.950" lastattention="1900-01-01T00:00:00.950" clientapp="EntityFramework" hostname="MSR-PRD-BDB02" hostpid="43440" loginname="IUSR_BuildDB" isolationlevel="read committed (2)" xactid="255115931225" currentdb="5" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
   <executionStack>
    <frame procname="adhoc" line="1" stmtstart="66" stmtend="7378" sqlhandle="0x02000000638e8b1acc45f82c476cd42914e32866e87c4fd60000000000000000000000000000000000000000">
unknown    </frame>
    <frame procname="unknown" line="1" sqlhandle="0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000">
unknown    </frame>
   </executionStack>
   <inputbuf>
(@p__linq__0 int,@p__linq__1 int)SELECT 
[Project1].[CachedBuildStateId] AS [CachedBuildStateId], …
Run Code Online (Sandbox Code Playgroud)

sql-server deadlock extended-events sql-server-2016

12
推荐指数
1
解决办法
320
查看次数

无法执行查询,甚至无法生成估计执行计划

我正在研究SQL Server 2019

我有一个表dbo.AllDates其中包含从19902050的所有日期。我有另一个表dbo.ActualExchangeRates,其中我有在给定来源中找到汇率的日期某些货币的实际汇率。

我正在尝试编写一个查询来获取2010 年2020 年之间所有日期的所有货币。如果找到比率,则写入比率,否则写入NULL

鉴于这种情况和下面给出的代码,有人可以帮助我理解为什么SELECT查询没有生成任何结果,甚至无法看到估计的执行计划吗?

CREATE TABLE dbo.AllDates(Date date)
CREATE TABLE dbo.ActualExchangeRates(Date date, Currency char(3), Rate real)

--Query 1: Not generating any results or estimated plan
SELECT      d.Date, m.Currency, c.Rate
FROM        dbo.AllDates d
INNER JOIN  (
    select
      currency,
      '20100101' as mindate,
      '20201231' as maxdate
    from dbo.ActualExchangeRates
    group by currency
) as m on d.date between m.mindate and m.maxdate
LEFT …
Run Code Online (Sandbox Code Playgroud)

sql-server execution-plan sql-server-2019 query-performance

12
推荐指数
2
解决办法
928
查看次数