在最大内存设置为 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
我有 SQL Server 2014,最大内存设置为 6GB(物理内存为 8GB)。
在目标服务器内存为6GB,有时,然后回落到总的服务器内存(约5.3GB,从未达到6GB)。我用committed_kb在sys.dm_os_sys_info检查SQL Server所使用的内存。
当我监视sys.dm_os_buffer_descriptors 时,我看到页面已从缓存中删除 - 但仍有 700MB 的内存。如果不需要内存,您如何解释从缓存中删除页面的事实?我希望 SQL Server 仅在需要内存时删除页面。
解除分配的临时表在此服务器上不是问题。我的 PLE 是 3632。过程缓存是 2182 MB。
我希望只有在没有剩余内存时才会删除页面,但是我有 700MB 可用空间还是我误解了这一点?
有人可以尝试解释这种行为吗?
SQL Server 也在从磁盘读取,所以我想我可能会得出结论,并非所有需要的页面都在内存中。
我做了一些更多的研究,我将大量页面从磁盘读取到内存中,并在读取过程中注意到任务管理器中的一些内容:
就像 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) 我们有一个第三方应用程序,可以批量发送 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) 正如我在这个问题中提到的,我试图了解时钟指针的工作原理。只需在内存压力时将时钟指针移动,即可移除缓存条目或降低成本。
根据我所学到的,我现在尝试解释dm_os_memory_cache_clock_hands. 当我检查dm_os_memory_cache_clock_hands我的一台服务器(SQL Server 2016 SP1,32 RAM)时,我对我所看到的感到有些困惑。
在round_start_time为CACHESTORE_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) 在 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
我们有一个最大内存设置为 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。因此,这可能是高编译的原因。
有没有办法测量(性能,扩展事件,...)从缓存中删除计划?所以我可以确定本地内存压力真的是高编译的原因吗?
我有一个大约有 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
我们有一个带有两个实例的物理 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
我需要重建一些大索引,并且我正在使用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
在BOL 上,我阅读了以下关于MultiSubnetFailover=True 的内容:
即使可用性组仅跨越单个子网,MultiSubnetFailover连接选项也应设置为True。这允许您预先配置新客户端以支持未来跨子网,而无需更改未来客户端连接字符串,并且还优化了单个子网故障转移的故障转移性能。
据我了解MultiSubnetFailover,使用此选项设置客户端驱动程序为与侦听器关联的每个 IP 地址设置一个套接字。它们都被并行检查以加快查找在线 IP 的过程,第一个响应将用于连接。在这里,我看到了性能提升。
但是单个子网的性能提升在哪里?只有与侦听器关联的 IP。
sql-server ×8
performance ×2
tempdb ×2
clustering ×1
heap ×1
index-tuning ×1
memory ×1
plan-cache ×1
sorting ×1