小编Fre*_*gen的帖子

排序溢出到 tempdb 但估计行等于实际行

在最大内存设置为 25GB 的 SQL Server 2016 SP2 上,我们有一分钟执行大约 80 次的查询。该查询将大约 4000 页溢出到 tempdb。这会导致 tempdb 的磁盘上出现大量 IO。

当您查看查询计划(简化查询)时,您会看到估计行数等于实际行数,但仍然会发生溢出。所以过时的统计数据不能成为问题的原因。

我做了一些测试和以下查询溢出到 Tempdb:

select id --uniqueidentifier
from SortProblem
where [status] ='A'
order by SequenceNumber asc
option (maxdop 1)
Run Code Online (Sandbox Code Playgroud)

但是,如果我选择不同的列,则不会发生溢出:

select startdate --datetime
from SortProblem
where [status] ='A'
order by SequenceNumber asc 
option (maxdop 1)
Run Code Online (Sandbox Code Playgroud)

所以我试图“放大” id 列的大小:

select CONVERT(nvarchar(512),id)
from SortProblem
where [status] ='A'
order by SequenceNumber asc 
option (maxdop 1)
Run Code Online (Sandbox Code Playgroud)

然后也不会发生溢出。

为什么 uniqueidentifier 不会溢出到 tempdb 和 datatime 列?当我删除大约 20000 条记录时,当我选择 id …

sql-server tempdb sorting sql-server-2016 cardinality-estimates

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

SQL Server 未使用所有内存

我有 SQL Server 2014,最大内存设置为 6GB(物理内存为 8GB)。

目标服务器内存为6GB,有时,然后回落到总的服务器内存(约5.3GB,从未达到6GB)。我用committed_kbsys.dm_os_sys_info检查SQL Server所使用的内存。

当我监视sys.dm_os_buffer_descriptors 时,我看到页面已从缓存中删除 - 但仍有 700MB 的内存。如果不需要内存,您如何解释从缓存中删除页面的事实?我希望 SQL Server 仅在需要内存时删除页面。

解除分配的临时表在此服务器上不是问题。我的 PLE 是 3632。过程缓存是 2182 MB。

我希望只有在没有剩余内存时才会删除页面,但是我有 700MB 可用空间还是我误解了这一点?

有人可以尝试解释这种行为吗?

SQL Server 也在从磁盘读取,所以我想我可能会得出结论,并非所有需要的页面都在内存中。

我做了一些更多的研究,我将大量页面从磁盘读取到内存中,并在读取过程中注意到任务管理器中的一些内容:

  • 使用的内存从 7.0GB -> 7.2GB -> 7.0GB -> 7.2GB ->...
  • Sqlservr.exe 从 5.3GB -> 5.5GB -> 5.3GB -> 5.5GB -> ...

就像 Windows 不允许sqlservr.exe增长到 6GB 一样。

我运行了 Shanky 提供的查询:

select
(physical_memory_in_use_kb/1024) Physical_Memory_usedby_Sqlserver_MB,
(locked_page_allocations_kb/1024 )Locked_pages_used_Sqlserver_MB,
(Virtual_address_committed_kb/1024 )Total_Memory_in_MB,--RAM+ …
Run Code Online (Sandbox Code Playgroud)

sql-server memory sql-server-2014

13
推荐指数
2
解决办法
2万
查看次数

每个批次都会导致编译

我们有一个第三方应用程序,可以批量发送 T-SQL 语句。

该数据库托管在 SQL Server 2016 Enterprise SP1 CU7、16 核和 256GB 内存上。已启用 Ad-Hoc 优化。

这是正在执行的查询的虚拟示例:

exec sp_executesql N'
IF @@TRANCOUNT = 0 SET TRANSACTION ISOLATION LEVEL SNAPSHOT

select field1, field2 from table1 where field1=@1
option(keep plan, keepfixed, loop join)

select field3, field4 from table2 where field3=@1
option(keep plan, keepfixed, loop join)', N'@1 nvarchar(6)',@1=N'test'
Run Code Online (Sandbox Code Playgroud)

当我监视数据库并查看批处理/秒和编译/秒时,我注意到它们总是相同的。在重负载下,这可以是 1000 批/秒和 1000 次编译/秒。在平均负载下,有 150 个批次/秒。

我分析了最近编译计划的查询缓存:

SELECT TOP (1000) qs.creation_time
    , DatabaseName = DB_NAME(st.dbid)
    , qs.execution_count
    , st.text
    , qs.plan_handle
    , qs.sql_handle
    , qs.query_hash …
Run Code Online (Sandbox Code Playgroud)

performance sql-server sql-server-2016 query-performance

10
推荐指数
2
解决办法
422
查看次数

dm_os_memory_cache_clock_hands 理解

正如我在这个问题中提到的,我试图了解时钟指针的工作原理。只需在内存压力时将时钟指针移动,即可移除缓存条目或降低成本。

根据我所学到的,我现在尝试解释dm_os_memory_cache_clock_hands. 当我检查dm_os_memory_cache_clock_hands我的一台服务器(SQL Server 2016 SP1,32 RAM)时,我对我所看到的感到有些困惑。

round_start_timeCACHESTORE_SQLCP 约为31小时,所以,我觉得,因为它需要一段时间来完成这一轮缓存中没有遭受大量的内存压力。另一方面,我看到last_tick_time每次刷新都会改变,所以手在移动。另一个奇怪的事实是这种removed_all_rounds_count情况也在发生变化。所以条目从缓存中删除。将clock_status始终暂停。在removed_last_round_count大约68000。

所以我的结论是有压力,CACHESTORE_SQLCP因为手在移动、removed_all_rounds_count变化和removed_last_round_count高。
这是对 dmv 的正确解释吗?

我不明白的是为什么round_start_time在 32GB 的服务器上如此之高,而且手一直在移动。

我使用以下脚本(我在Tigertoolbox 中找到的)转换last_tick_time为日期时间:

    declare @ticks_per_ms bigint,@now DATETIME
    select @ticks_per_ms=ms_ticks from sys.dm_os_sys_info
    set @now=getdate()

    CASE WHEN last_tick_time BETWEEN -2147483648 AND 2147483647 AND 
         @ticks_per_ms BETWEEN -2147483648 AND 2147483647 
    THEN DATEADD(ms, last_tick_time - @ticks_per_ms, @now) 
    WHEN last_tick_time/1000 BETWEEN -2147483648 …
Run Code Online (Sandbox Code Playgroud)

sql-server database-internals

10
推荐指数
1
解决办法
270
查看次数

由于 varchar(max) 对 tempdb 的溢出排序

在 32GB 的服务器上,我们运行 SQL Server 2014 SP2,最大内存为 25GB,我们有两个表,在这里您可以找到两个表的简化结构:

CREATE TABLE [dbo].[Settings](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [resourceId] [int] NULL,
    [typeID] [int] NULL,
    [remark] [varchar](max) NULL,
    CONSTRAINT [PK_Settings] PRIMARY KEY CLUSTERED ([id] ASC)
) ON [PRIMARY]
GO

CREATE TABLE [dbo].[Resources](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [resourceUID] [int] NULL,
 CONSTRAINT [PK_Resources] PRIMARY KEY CLUSTERED ([id] ASC)
) ON [PRIMARY]
GO
Run Code Online (Sandbox Code Playgroud)

具有以下非聚集索引:

CREATE NONCLUSTERED INDEX [IX_UID] ON [dbo].[Resources]
(
    [resourceUID] ASC
)

CREATE NONCLUSTERED INDEX [IX_Test] ON [dbo].[Settings]
(
    [resourceId] ASC,
    [typeID] ASC …
Run Code Online (Sandbox Code Playgroud)

performance sql-server tempdb cardinality-estimates query-performance

10
推荐指数
2
解决办法
636
查看次数

衡量计划驱逐

我们有一个最大内存设置为 24GB 的 SQL Server 2016 SP1。
该服务器有大量编译,这些编译中只有 10% 来自 Ad-Hoc 查询。所以新编译的计划应该存储在计划缓存中,但计划缓存的大小没有增加(大约 3.72GB)。

我怀疑存在导致从缓存中删除计划的本地内存压力。计划缓存压力限制为 5GB。(0-4GB 可见目标内存的 75% + 4GB-64GB 可见目标内存的 10% + 可见目标内存的 5%>64GB)。当缓存存储达到压力限制的 75% 时,应从缓存中删除计划。就我而言,5 GB 的 75% 是 3.75 GB。因此,这可能是高编译的原因。

有没有办法测量(性能,扩展事件,...)从缓存中删除计划?所以我可以确定本地内存压力真的是高编译的原因吗?

database-internals plan-cache sql-server-2016

9
推荐指数
1
解决办法
744
查看次数

如果它是一个堆,一个表会受益吗

我有一个大约有 1.500.000 行的日志记录表,主键是一个升序标识,聚集索引在主键上。标识值是自动生成的 => 记录总是添加在最后。平均行大小为 1570 字节。

由于频繁添加新行,因此有很多页面拆分。没有行被更新/删除,并且表上有一个非聚集索引,因此可以选择行。由于页面拆分,聚集索引总是碎片化 > 65%。

我想知道我的表是否会因删除聚集索引并使其成为堆表而受益?

这是我的表 + 非聚集索引的样子:

CREATE TABLE [dbo].[LogEntry](
[Id] [bigint] IDENTITY(1,1) NOT NULL,
[Application] [varchar](20) NOT NULL,
[EntityFullName] [varchar](80) NOT NULL,
[Action] [int] NOT NULL,
[UserName] [varchar](25) NOT NULL,
[TimeStamp] [datetime] NOT NULL,
[EntityId] [varchar](50) NOT NULL,
[WhatChanged] [nvarchar](max) NULL,
CONSTRAINT [PK_LogEntry] PRIMARY KEY CLUSTERED(     
   [Id] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 100) ON [PRIMARY] ) 
ON [PRIMARY] …
Run Code Online (Sandbox Code Playgroud)

sql-server clustered-index index-tuning heap sql-server-2012

7
推荐指数
1
解决办法
1290
查看次数

Alwayson AG 租约超时和健康检查超时

我们有一个带有两个实例的物理 SQL Server 2016 Enterprise SP2,每个实例包含一个 AG。有时会发生一个AG去resolve(没有failover),集群资源在500ms后自动重启,然后一切又重新上线。但是我还没有找到原因。

当我检查错误日志时,我看到以下条目:

日期 14/04/2019 23:35:37
SQL Server 托管可用性组“AG_PROD”在租用超时期限内未收到来自 Windows Server 故障转移群集的进程事件信号。

日期 14/04/2019 23:35:37
SQL Server 托管可用性组“AG_PROD”在租用超时期限内未收到来自 Windows Server 故障转移群集的进程事件信号。

日期 14/04/2019 23:35:14
SQL Server 在数据库 ID 6 中的文件 [e:\sqlData\db.mdf] 上遇到了 1 次 I/O 请求需要超过 15 秒才能完成。操作系统文件句柄是 0x0000000000001128。最新的long I/O的偏移量为:0x00010de65c0000

日期 14/04/2019 23:33:10
BACKUP DATABASE WITH DIFFERENTIAL 在 61.045 > 秒(6.585 MB/秒)内成功处理了 51459 页。

如您所见,有一个 IO 请求需要的时间超过 15 秒,我希望能在*_SQLDIAG_*.xel文件中找到它,但此处未发现任何错误。

当我检查集群日志时,我发现以下内容:

2019/04/14-23:35:09.430 INFO [NM] 收到来自客户端地址 SQL1 的请求。
2019/04/14-23:35:09.444 INFO [NM] 收到来自客户端地址 SQL1 的请求。
2019/04/14-23:35:09.459 …

clustering database-internals availability-groups sql-server-2016

6
推荐指数
0
解决办法
5179
查看次数

在线索引在中间级别重建更高的碎片

我需要重建一些大索引,并且我正在使用ALTER INDEX语句的各种选项(sort_in_tempdb、maxdop、online)对具有 4 个级别和叶级别的 800000 页的测试索引进行一些测试。
我注意到,当我使用Online=on索引的中间页(级别 1)运行语句时,与以前一样碎片化程度更高(89% 而不是 3%)。

中间页只有在我设置MAXDOP=1. 使用选项SORT_IN_TEMBP=ON,ONLINE=OFF,级别 2 碎片从 0 跳到 100。

以下是导致级别 1 碎片增加的语句:

ALTER INDEX pk_test ON dbo.test REBUILD WITH (sort_in_tempdb=off,online=on,maxdop=1)
ALTER INDEX pk_test ON dbo.test REBUILD WITH (sort_in_tempdb=off,online=on)
ALTER INDEX pk_test ON dbo.test REBUILD WITH (sort_in_tempdb=on,online=on)
Run Code Online (Sandbox Code Playgroud)

此语句导致级别 2 上的碎片从 0 变为 100,但级别 1 保持不变:

ALTER INDEX pk_test ON dbo.test REBUILD WITH (sort_in_tempdb=on,online=off)
Run Code Online (Sandbox Code Playgroud)

中间页面上的碎片是否需要担心?是什么导致碎片增加?

sql-server sql-server-2016 enterprise-edition index-maintenance

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

使用 MultiSubnetFailover 提高单个子网的性能

BOL 上,我阅读了以下关于MultiSubnetFailover=True 的内容:

即使可用性组仅跨越单个子网MultiSubnetFailover连接选项也应设置为True。这允许您预先配置新客户端以支持未来跨子网,而无需更改未来客户端连接字符串,并且还优化了单个子网故障转移的故障转移性能

据我了解MultiSubnetFailover,使用此选项设置客户端驱动程序为与侦听器关联的每个 IP 地址设置一个套接字。它们都被并行检查以加快查找在线 IP 的过程,第一个响应将用于连接。在这里,我看到了性能提升。

但是单个子网的性能提升在哪里?只有与侦听器关联的 IP。

sql-server availability-groups sql-server-2017

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