SQL Server 2014 引入了sys.dm_exec_query_profiles DMV,它提供了一种监视执行查询的实时进度的方法。最近我在查看 SQL Server 2016 SP1 中的一个有点复杂的查询,并注意到它sys.dm_exec_query_profiles包含查询计划中不存在的额外节点。这些节点必须???为physical_operator_name:
对于查询的并行版本,只有一个隐藏节点。该节点有一个object_id与嵌套循环连接的内表相关联。根据node_id这里是节点应该出现的地方:
运行查询会MAXDOP 1产生更多的隐藏节点。该???节点出现在与之前相同的位置:
还有一个新的没有出现在平行计划中:
这些似乎只出现在一些嵌套循环连接周围。我不记得在 SQL Server 2014 上看到过这种行为。不幸的是,查询很复杂,我无法上传匿名计划。
这里发生了什么?为什么sys.dm_exec_query_profiles报告没有显示在图形计划中的额外查询计划节点?
BIT列在聚集列存储索引中使用时是否提供任何性能优势?例如,我对在 CCI 中定义列BIT而不是 所获得的任何性能优势感兴趣BIGINT。我正在使用 SQL Server 2016。
我对 CCI 压缩的工作原理知之甚少,但根据我所阅读的内容和一些测试,似乎数据类型(仅限于存储整数的精确数字)在列存储压缩方面确实无关紧要. 例如,如果我将 10 个完整的行组插入到带有BIGINT列而不是BIT列的表中,我看不到压缩行组之间的大小差异。以下是一项测试的源数据:
DROP TABLE IF EXISTS dbo.CCI_BIT_TEST_SOURCE;
CREATE TABLE dbo.CCI_BIT_TEST_SOURCE (
ID1 BIGINT NOT NULL,
ID2 BIGINT NOT NULL,
ID_BIT BIT NOT NULL,
ID_BIGINT BIGINT NOT NULL,
INDEX CCI__CCI_BIT_TEST_SOURCE CLUSTERED COLUMNSTORE
);
INSERT INTO dbo.CCI_BIT_TEST_SOURCE WITH (TABLOCK)
SELECT
t.RN
, t.RN
, t.RN % 2
, t.RN % 2
FROM
(
SELECT TOP (10485760) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) …Run Code Online (Sandbox Code Playgroud) 我想知道 SQL Server 如何生成“自动创建统计信息”设置为“关闭”的查询计划。
我在搜索答案时偶然发现了以下链接中的以下上下文(对不起,我搜索了,但找不到更好的)。
https://www.simple-talk.com/sql/performance/execution-plan-basics/
表变量从来没有生成统计信息,所以优化器总是假设它们只有一行,而不管它们的实际大小
虽然上面只适用于表变量,但我认为SQL Server会使用相同的原理来导出表的查询计划并决定做一个小测试。
我清除了 PROC 缓存并在具有 100 万条记录的表上运行以下查询
我的测试证明我错了,SQL Server 报告缺少统计数据(如预期),但是当没有统计数据时,估计行数为 31622(我预计为 1)。查询优化器是如何在没有统计信息的情况下得出这个值的?
我有一个通过 C# 代码实现的 CLR 标量 UDF。我注意到,与String数据类型相比,将SqlString数据类型用于输入参数可以显着提高性能。在通往 SQLCLR 级别 5 的阶梯:开发(在 SQL Server 中使用 .NET)中,Solomon Rutzky提到了以下原因更喜欢字符串的 SQL 数据类型:
本机公共语言运行时 (CLR) 数据类型和 SQL Server 数据类型之间的主要区别在于,前者不允许 NULL 值,而后者提供完整的 NULL 语义。
...
可以通过 N[VAR]CHAR 的 SqlChars、[VAR]BINARY 的 SqlBytes 和 XML 的 SqlXml.CreateReader() 来实现流值...
...
使用 SqlString(不是字符串,甚至不是 SqlChars)时,您可以访问 CompareInfo、CultureInfo、LCID 和 SqlCompareOptions 属性...
我知道我的输入永远不会为 NULL,我不需要将值传入,并且我永远不会检查排序规则属性。我的情况可能是一个例外,最好使用String而不是SqlString?如果我确实采用这种方法,有什么需要特别注意的吗?
如果重要的话,我正在使用 SQL Server 的默认排序规则。这是我的源代码的一部分,s1作为输入参数:
fixed (char* chptr = s1)
{
char* cp = (char*)current;
for (int i …Run Code Online (Sandbox Code Playgroud) 考虑以下用户无权执行的 T-SQL SP_TRACE_GENERATEEVENT:
SET XACT_ABORT OFF;
SET ANSI_WARNINGS ON;
BEGIN TRANSACTION;
BEGIN TRY
EXEC SP_TRACE_GENERATEEVENT;
END TRY
BEGIN CATCH
END CATCH;
COMMIT TRANSACTION;
Run Code Online (Sandbox Code Playgroud)
当 ANSI_WARNINGS=OFF 时,权限违规会导致事务中止。
但是,我收到以下错误,如 dbfiddle 中所示:
消息 3930 级别 16 状态 1 第 11 行 当前事务无法提交,并且无法支持写入日志文件的操作。回滚事务。
消息 3998 级别 16 状态 1 第 1 行 在批处理结束时检测到不可提交的事务。事务被回滚。
除了调用 SP_TRACE_GENERATEEVENT 之外,其他类型的安全问题也可能会发生此问题。例如,我在尝试查询用户无法连接到该数据库的表时看到过它。我没有完整的错误案例列表。
为什么权限错误会导致XACT_ABORTset toOFF和ANSI_WARNINGSset to 的事务失败ON?
在 SQL Server 中,我使用以下代码删除带有约束的表:
IF OBJECT_ID('EMPLOYEES') IS NOT NULL
BEGIN
ALTER TABLE EMPLOYEES DROP CONSTRAINT EMP_DEPT_FK
DROP TABLE EMPLOYEES;
END
Run Code Online (Sandbox Code Playgroud)
如何在 Mysql 中完成同样的事情?
是否有其他人在调用CHANGETABLESQL Server 2016时遇到过糟糕的计划?
我有一个使用更改跟踪来更新缓存的应用程序。应用服务器每秒获取多个表的更改。在CHANGETABLE如此频繁,通常仅返回几行调用。这在 2008 R2 和 2012 中效果很好。当我测试 2016 时,我发现 CPU 飙升,并发现该计划正在扫描更改跟踪内部表,它曾经在那里进行搜索。
如果您想在此处查看此行为,请执行复制它的步骤:
创建表:
CREATE TABLE [dbo].[ChangeTable_Test](
[Id] [bigint] IDENTITY(1,1) NOT NULL,
[Name] [varchar](50) NOT NULL,
CONSTRAINT [PK_Test_ChangeTable_Id] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[ChangeTable_Test] ENABLE CHANGE_TRACKING
GO
INSERT INTO ChangeTable_Test (Name) VALUES ('Test')
GO 1000
Run Code Online (Sandbox Code Playgroud)包括实际的执行计划并运行以下命令。
SET STATISTICS IO …Run Code Online (Sandbox Code Playgroud)由于客户端应用程序将 PDF 文件存储为 varbinary,我有一个现有的旧表,大小约为 180GB。我希望能够在创建新解决方案时使用 GZIP 压缩所有行的该列以帮助节省空间(我希望有一种方法可以在 SQL 中执行此操作,而不必为此编写客户端代码)。我看到该COMPRESS方法可用于 Sql Server 2016,但我需要一个适用于 2008 的解决方案。任何想法将不胜感激。
在BOL 上,我阅读了以下关于MultiSubnetFailover=True 的内容:
即使可用性组仅跨越单个子网,MultiSubnetFailover连接选项也应设置为True。这允许您预先配置新客户端以支持未来跨子网,而无需更改未来客户端连接字符串,并且还优化了单个子网故障转移的故障转移性能。
据我了解MultiSubnetFailover,使用此选项设置客户端驱动程序为与侦听器关联的每个 IP 地址设置一个套接字。它们都被并行检查以加快查找在线 IP 的过程,第一个响应将用于连接。在这里,我看到了性能提升。
但是单个子网的性能提升在哪里?只有与侦听器关联的 IP。
我们的应用程序代码BINARY的一部分出于散列的目的将数据类型转换为 。例如,我们将BIGINT值转换为BINARY(8). 该文档警告说,SQL 服务器版本之间的转换可能会发生变化:
不保证任何数据类型和二进制数据类型之间的转换在 SQL Server 版本之间是相同的。
作为防御,每当我们开始支持新版本的 SQL Server 时,我们都会尝试运行测试以验证我们所有的转换仍然有效。对于类似的事情BIGINT,我们检查转换值的长度以获取 允许的最小值和最大值BIGINT。这希望意味着我们会知道,例如,SQL Server 2019 是否开始要求BINARY(9)拟合BIGINT.
我们如何进行这种类型的分析FLOAT(53)?现在我们认为所有可能的值都映射到适合 a 的唯一值BINARY(8),但我不知道如何验证它。这可能不像检查数据类型所需的字节数那么简单。例如,TIME数据类型需要 5 个字节存储,但必须转换为 aBINARY(6)以避免错误。也许这无关紧要,但也让我紧张到BINARY无法转换回FLOAT. 我承认我可能把问题想得太多,所以我欢迎框架挑战作为答案。
如何编写代码来验证所有可能的输入FLOAT(53)都不会溢出 aBINARY(8)并且两个不同的FLOAT(53)值不会转换为相同的BINARY(8)值?
sql-server ×9
columnstore ×1
compression ×1
constraint ×1
datatypes ×1
drop-table ×1
mysql ×1
performance ×1
sql-clr ×1
varbinary ×1