目的
在尝试创建自引用函数的测试示例时,一个版本失败而另一个版本成功。
唯一的区别是添加SELECT到函数体导致两者的执行计划不同。
起作用的功能
CREATE FUNCTION dbo.test5(@i int)
RETURNS INT
AS
BEGIN
RETURN(
SELECT TOP 1
CASE
WHEN @i = 1 THEN 1
WHEN @i = 2 THEN 2
WHEN @i = 3 THEN dbo.test5(1) + dbo.test5(2)
END
)
END;
Run Code Online (Sandbox Code Playgroud)
调用函数
SELECT dbo.test5(3);
Run Code Online (Sandbox Code Playgroud)
退货
(No column name)
3
Run Code Online (Sandbox Code Playgroud)
不起作用的功能
CREATE FUNCTION dbo.test6(@i int)
RETURNS INT
AS
BEGIN
RETURN(
SELECT TOP 1
CASE
WHEN @i = 1 THEN 1
WHEN @i = 2 THEN 2
WHEN @i = 3 …Run Code Online (Sandbox Code Playgroud) 在对稀疏列进行一些测试时,正如您所做的那样,出现了性能下降,我想知道其直接原因。
数据线
我创建了两个相同的表,一个有 4 个稀疏列,一个没有稀疏列。
--Non Sparse columns table & NC index
CREATE TABLE dbo.nonsparse( ID INT IDENTITY(1,1) PRIMARY KEY NOT NULL,
charval char(20) NULL,
varcharval varchar(20) NULL,
intval int NULL,
bigintval bigint NULL
);
CREATE INDEX IX_Nonsparse_intval_varcharval
ON dbo.nonsparse(intval,varcharval)
INCLUDE(bigintval,charval);
-- sparse columns table & NC index
CREATE TABLE dbo.sparse( ID INT IDENTITY(1,1) PRIMARY KEY NOT NULL,
charval char(20) SPARSE NULL ,
varcharval varchar(20) SPARSE NULL,
intval int SPARSE NULL,
bigintval bigint SPARSE NULL
);
CREATE INDEX IX_sparse_intval_varcharval …Run Code Online (Sandbox Code Playgroud) 信息
我的问题涉及一个中等大的表(~40GB 数据空间),它是一个堆
(不幸的是,我不允许应用程序所有者向该表添加聚集索引)
已创建 Identity 列 ( ID)上的自动创建统计信息,但该统计信息为空。
实际问题
据我了解,即使在完全相同的列(重复)上有两个统计数据,也可以使用所有统计数据并跟踪修改,那么为什么此统计数据仍为空?
统计信息
数据库统计信息
桌子尺寸
创建统计信息的列信息
[ID] [int] IDENTITY(1,1) NOT NULL
Run Code Online (Sandbox Code Playgroud)
身份栏
select * from sys.stats
where name like '%_WA_Sys_0000000A_6B7099F3%';
Run Code Online (Sandbox Code Playgroud)
获取有关另一个统计数据的一些信息
select * From sys.dm_db_stats_properties (1802541555, 3)
Run Code Online (Sandbox Code Playgroud)
与我的空数据相比:
来自“生成脚本”的统计数据 + 直方图:
/****** Object: Statistic [_WA_Sys_0000000A_6B7099F3] Script Date: 2/1/2019 10:18:19 AM ******/
CREATE STATISTICS [_WA_Sys_0000000A_6B7099F3] ON [dbo].[table]([ID]) WITH STATS_STREAM = 0x01000000010000000000000000000000EC03686B0000000040000000000000000000000000000000380348063800000004000A00000000000000000000000000
Run Code Online (Sandbox Code Playgroud)
创建统计数据的副本时,里面没有数据
CREATE STATISTICS [_WA_Sys_0000000A_6B7099F3_TEST] ON [dbo].[table]([ID]) WITH STATS_STREAM = 0x01000000010000000000000000000000EC03686B0000000040000000000000000000000000000000380348063800000004000A00000000000000000000000000
Run Code Online (Sandbox Code Playgroud)
手动更新统计信息时,它们确实会更新。
UPDATE STATISTICS …Run Code Online (Sandbox Code Playgroud) 介绍
简而言之,我的服务器上发生了很多临时查询,来自我无法控制且无法更改的应用程序(即使推送索引也很困难,而且它们使用了很多堆......)。
眼镜
操作系统 - Windows Server 2012 R2(主节点)SQL Server 2014 - 12.0.5546
Always On AG 与具有相同硬件的辅助同步节点 + Build。
由于许可,我们只能将 24 个内核中的 12 个用于 sql server(我没有这样做)。很容易发现哪个 12 个内核;)。

问题
现在关于我的问题。目前,我们每 30 分钟清除一次“TokenAndPermUserStore”。这甚至在它到达我手中之前就在服务器上发生了。我们使用以下命令执行此操作:
DBCC FREESYSTEMCACHE ('TokenAndPermUserStore')
Run Code Online (Sandbox Code Playgroud)
我使用这个查询来检查缓存:
SELECT SUM(pages_kb) / 1024 AS
"CurrentSizeOfTokenCache(mb)"
FROM sys.dm_os_memory_clerks
WHERE name = 'TokenAndPermUserStore'
Run Code Online (Sandbox Code Playgroud)
在清除之后,这是缓存大小:
CurrentSizeOfTokenCache(mb)
1602
Run Code Online (Sandbox Code Playgroud)
在某个时间点,例如清除后 15 分钟,这是缓存大小:
CurrentSizeOfTokenCache(mb)
1976
Run Code Online (Sandbox Code Playgroud)
更新: 现在,当 CPU 使用率再次稳定时(使用 40%(监控时为 20%),缓存远低于 CPU 使用率高时的最低点。
CurrentSizeOfTokenCache(mb)
1281
Run Code Online (Sandbox Code Playgroud)
昨天的例子:
昨天的这张照片上的下降非常明显:(注意因为我们可以使用 24 个内核中的 12 个,50% 意味着在监控软件中 100%,换句话说,cpu 使用率可能不会超过 50%,因为它专用于仅限 sql 服务器)
需要注意的一件重要事情是,昨天我们在 top …
我们一直在监控一些SQLServer: Memory Manager指标,并注意到在DBCC CheckDB工作后,指标
Database Cache Memory (KB)
Run Code Online (Sandbox Code Playgroud)
大幅下降。准确地说,它从 140 GB 缓存数据库内存下降到 60 GB。之后,在一周内再次缓慢上升。(“ Free Memory KB”的数量,紧随其后从 20 GB 增加到 100 GB CheckDB)
DBCC CheckDB 每周日运行,因此数据库缓存内存必须每周再次增加
What is the behavior of this ? Why CheckDB pushes database pages out of memory ?
Run Code Online (Sandbox Code Playgroud)
第二个问题是为什么“ buffer cache hit ratio”DBCC CheckDB完成后没有变化?
平均为 99.99%,在DBCC CheckDB工作后它下降到 ~98.00%,并很快恢复到 99%,而我预计“ buffer cache hit ratio”会显着下降,因为数据库数据必须再次从存储读取到 RAM?
sql-server dbcc-checkdb buffer-pool sql-server-2017 performance-monitor
在 SQL Server Always On Availability Group™ 的主要/次要副本上运行以下查询时
SELECT DISTINCT local_tcp_port,protocol_type,num_reads,num_writes
FROM sys.dm_exec_connections
WHERE local_net_address is not null;
Run Code Online (Sandbox Code Playgroud)
为数据库镜像协议显示了两个本地 tcp 端口,5022&63420
Server Name local_tcp_port protocol_type num_reads num_writes
ServerName 5022 Database Mirroring 102942598 5
ServerName 63420 Database Mirroring 5 89655349
Run Code Online (Sandbox Code Playgroud)
该5022端口是预期的,因为这是配置为镜像端点的端口。
另一个似乎是一个动态端口,为什么使用这个端口以及用于什么?
是否与一个显示大量读取 ( 5022) 和另一个显示大量写入 ( 63420)的事实有关。
构建版本:13.0.5264.1
以下查询需要大约 10 秒才能在具有 12k 条记录的表上完成
select top (5) *
from "Physician"
where "id" = 1 or contains("lastName", '"a*"')
Run Code Online (Sandbox Code Playgroud)
但是,如果我将 where 子句更改为
where "id" = 1
Run Code Online (Sandbox Code Playgroud)
或者
where contains("lastName", '"a*"')
Run Code Online (Sandbox Code Playgroud)
它会立即返回。
两列都被索引,lastName 列也被全文索引。
CREATE TABLE Physician
(
id int identity NOT NULL,
firstName nvarchar(100) NOT NULL,
lastName nvarchar(100) NOT NULL
);
ALTER TABLE Physician
ADD CONSTRAINT Physician_PK
PRIMARY KEY CLUSTERED (id);
CREATE NONCLUSTERED INDEX Physician_IX2
ON Physician (firstName ASC);
CREATE NONCLUSTERED INDEX Physician_IX3
ON Physician (lastName ASC);
CREATE FULLTEXT INDEX
ON …Run Code Online (Sandbox Code Playgroud) 我有几个关于数据缓存如何工作的问题
想象一下我们有以下情况:
服务器重新启动或我们刚刚运行 DBCC DROPCLEANBUFFERS
我们有一个Table150 GB 并且有列A, B, C, D, E。
列A是聚集索引键,列B和C对他们的非聚集索引。
当我们做
select top 100 * from Table1
Run Code Online (Sandbox Code Playgroud)
整个聚集索引(表)是否从磁盘读取到内存,即使我们只需要 100 行?还是只有 100 行(它们的数据页)从磁盘读取到内存?
与非聚集索引相同,当我们这样做时
select top 100 * from Table1 where column B = 'some value'
Run Code Online (Sandbox Code Playgroud)
整个非聚集索引+聚集索引是否被加载到内存中?或者只有来自非聚集索引的 100 行和来自聚集索引的 100 行?
我已使用以下语法在我们的一台服务器上运行sp_WhoIsActive:
sp_whoisactive @get_plans = 1, @show_sleeping_spids = 0, @get_outer_command = 1, @get_locks = 1
Run Code Online (Sandbox Code Playgroud)
并用sql_command(显示的列@get_outer_command设置为1)找到了一个spid,如下所示
(@p1 int,@p2 int)
Exec MyDatabase.MyProc @p1 @p2
Run Code Online (Sandbox Code Playgroud)
当我尝试在我的测试 Adventureworks 数据库上使用此语法运行查询时:
(@be int)
SELECT *
FROM Person.Person
WHERE BusinessEntityID = @be
Run Code Online (Sandbox Code Playgroud)
我收到错误
消息 1050,级别 15,状态 1,第 1 行 此语法仅适用于参数化查询。消息 137,级别 15,状态 2,第 4 行 必须声明标量变量“@FN”。
所以这似乎与参数化查询有关。这是有道理的,因为变量 @be 永远不会被设置为一个值
这里发生了什么?
我正在尝试批量重新输入列。这意味着首先删除并重新创建它们所属的任何约束。
我发现这些约束引用的列
但我找不到计算列。
我已经研究过INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE,但它不包括计算列。
还有sys.computed_columnswhich 显示定义,但不以可搜索的方式列出列。
我还有其他地方可以看吗?如果 SQL Server 可以弄清楚依赖关系,我想我也可以。
sql-server ×10
buffer-pool ×1
cache ×1
dbcc-checkdb ×1
dmv ×1
functions ×1
memory ×1
optimization ×1
parameter ×1
statistics ×1
syntax ×1
t-sql ×1