小编Fre*_*gen的帖子

由于数据倾斜,嵌套循环的估计值非常低

在 SQL Server 2016 SP2 上,我们有一个查询对嵌套循环运算符的估计非常低。由于估计值较低,此查询也会溢出到 tempdb。

如果我是正确的,SQL Server 2014+ 使用粗直方图估计来计算连接的估计行数。
但是当我执行查询时,SQL Server 使用密度向量来计算估计的行数。如果没有子句,
SQL Server 是否仅使用粗直方图估计where

通常,当我有一个包含倾斜数据的表时,我会使用过滤的统计数据来改进估计。但在这种情况下,这似乎不起作用。

有没有办法改进嵌套循环的估计?

使用以下代码可以重现数据:

create table MyTable
(
    id int identity,
    field varchar(50),
    constraint  pk_id primary  key clustered (id)
)
go

create table SkewedTable
(
    id int identity,
    startdate datetime,
    myTableId int,
    remark varchar(50),
    constraint  pk_id primary  key clustered (id)
)

set nocount on

insert into MyTable select top 1000 [name] from master..spt_values …
Run Code Online (Sandbox Code Playgroud)

performance sql-server sql-server-2016 cardinality-estimates query-performance

5
推荐指数
1
解决办法
605
查看次数

checkdb前后全备份

最近有人告诉我我应该在 dbcc checkdb 之前和 checkdb 之后进行一次完整备份,即使在完全恢复中也是如此。有人可以解释我为什么要这样做吗?

我认为在 checkdb 之前进行完整备份是不必要的(在完整恢复中),因为我总是可以恢复上次完整备份 + 差异备份 + t-log 备份。这是一个错误的假设吗?

sql-server backup dbcc-checkdb

4
推荐指数
1
解决办法
1421
查看次数

SQL Server 2016 AlwaysOn VDI_CLIENT_WORKER 命令

我在 SQL Server 2016 SP1 Standard 上设置了 AlwaysOn AG。然后我创建了一个 AG 并添加了一个带有自动种子(同步模式)的数据库。我使用 SSMS 2017 来创建我的 AG 并添加数据库。一切正常。

但是,当我检查等待统计信息时,我在主服务器上获得了 VDI_CLIENT_OTHER (80%) 类型的等待,平均资源时间为 42 秒。经过一番研究,我发现等待是由执行命令 VDI_CLIENT_WORKER 的 4 个会话生成的。据我了解,等待意味着在播种新 AG 时线程正在等待工作。但我不明白的是为什么我有那些等待,因为我的 AG 准备好了,为什么我有 4 个执行 VDI_CLIENT_WORKER 命令的会话?我发现每个调度程序都有一个 VDI_CLIENT_WORKER

有人可以尝试解释 VDI_CLIENT_WORKER-command 的作用以及如何解决许多 VDI_CLIENT_OTHER 等待的问题吗?

sql-server availability-groups sql-server-2016

4
推荐指数
1
解决办法
3099
查看次数

更新统计信息后查询计划不会失效

我正在运行一些测试以找出更新统计信息后查询计划何时失效。我用于测试的机器是 SQL Server Developer 2016 SP1 CU7。

我在BrentOzar.com上找到了一篇关于如何跟踪重新编译的文章,但我从未得到重新编译。 Auto Update Statistics并且Auto Create Statistics都启用

这是我的测试:

/* Create a table and put over 1k rows in it (to get past the 500 row stats threshold) */
CREATE TABLE dbo.MyTable (ID INT IDENTITY(1,1) PRIMARY KEY CLUSTERED, StringField VARCHAR(50));
GO
INSERT INTO dbo.MyTable(StringField) 
SELECT 'Stuff' FROM sys.all_objects;
GO

/* Start a trace monitoring recompiles */
exec sp_BlitzTrace @Action='start', @TargetPath='c:\temp\', @SessionId=@@SPID, @TraceRecompiles=1;
GO
SELECT * FROM dbo.MyTable WHERE StringField = …
Run Code Online (Sandbox Code Playgroud)

statistics extended-events sql-server-2016

3
推荐指数
1
解决办法
347
查看次数

手动 AG 故障转移后超出最大工作线程数

我们有两个 SQL Server 2016 SP2 CU6 Enterprise 在物理硬件(32 核)上运行,其中一个 AG 包含 5 db。二级不可读。今天我们做了一个有计划的手动故障转移,所以我们可以在另一台服务器上做维护工作。我们在没有重负载的情况下进行了故障转移。

故障转移是通过 SSMS 的 GUI 执行的,没有出现错误。但是几分钟后,我们接到了很多用户无法登录的电话。我们第一次尝试进行故障排除是与 SSMS 建立连接,但这给出了我们无法连接的错误,我不记得确切的错误消息。

接下来我们在记事本中查看错误日志文件,它就像SQL Server引擎挂起一样。故障转移后没有新条目添加到日志中。

由于问题的紧迫性,我们重新启动了主服务器上的 SQL Server 服务,问题消失了。
我们本可以尝试建立 DAC 连接以查看问题所在,但目的是让服务器尽快恢复在线状态。

一切恢复正常后,我们开始分析日志文件。
在旧主服务器的错误日志中,我们发现了几个错误 35278。在故障转移时没有长时间运行的事务在运行。

接下来是 AlwaysON_health 事件文件,这里的条目在故障转移后刚刚停止。

接下来我们看了一下*_*_SQLDIAG_*_*.xel文件。在这里,我们很幸运。

我们注意到的第一件事是:

<queryProcessing maxWorkers="960" workersCreated="1064"
 workersIdle="23" tasksCompletedWithinInterval="19" pendingTasks="34"
 oldestPendingTaskWaitingTime="1316776"
Run Code Online (Sandbox Code Playgroud)

由于某种原因,超过了最大工人数量,这可以解释为什么没有人可以连接。

这是待处理的任务:

<pendingTasks><br>
   <entryPoint name="Process Command" count="14" /><br>
   <entryPoint name="SNI New Connection" count="2" /><br>
   <entryPoint name="SNI Accept Done" count="3" /><br>
   <entryPoint moduleName="sqlmin.dll" imageBase="0x7ff827e80000" size="0x251e000" address="0x7ff8286622e0" count="6" /><br>
   <entryPoint moduleName="sqlmin.dll" imageBase="0x7ff827e80000" size="0x251e000" address="0x7ff8292b1190" count="2" /><br> …
Run Code Online (Sandbox Code Playgroud)

troubleshooting availability-groups sql-server-2016

3
推荐指数
1
解决办法
604
查看次数

收缩数据库可以提高性能吗

昨天我收到一封来自我们的供应商的邮件,提到他们的应用程序存在性能问题。

我还不知道问题是什么,但他们提出的解决方案是缩小数据库(因为有很多可用空间)。据我所知,这不会导致性能改进,但显然他们在其他客户申请时使用这种方法取得了成功。

我认为缩小发生的方式是将页面从文件的后面移动到前面,就像这样压缩数据库并导致大量碎片。

范围扫描是否有可能利用压缩数据库?
或者还有其他一些边缘情况可以从缩小数据库中受益吗?

performance sql-server-2016

3
推荐指数
1
解决办法
341
查看次数

差异备份失败并出现错误 3035,但日志备份成功

我们有一个 SQL Server 2014 Enterprise,其中 DIFF 备份失败。
这是我们收到的错误消息:

消息 3035,级别 16,状态 1,服务器 sqltest,第 1 行
无法对数据库“database1”执行差异备份,因为当前数据库备份不存在。通过重新发出 BACKUP DATABASE 来执行完整数据库备份,忽略WITH DIFFERENTIAL 选项。

分析以下查询的输出后,我们注意到第三方工具正在进行快照备份。

    select top 20 bs.type,bs.database_backup_lsn,bs.checkpoint_lsn,bs.backup_start_date,bs.is_snapshot,
    bs.is_copy_only,bs.user_name
    from dbo.backupset bs
    where bs.database_name = 'database1'
    order by backup_start_date desc
Run Code Online (Sandbox Code Playgroud)

根据Pinal Dave 的说法,这些工具使用 VSS 进行备份,这不是正常的完整备份。

我不明白的是为什么LOG备份会成功?据我所知,它们也是基于最后一次完整备份的。
有人可以向我解释这种差异吗?

sql-server backup database-internals

2
推荐指数
1
解决办法
303
查看次数