SQL Server 2019的第一个CTP中的新增功能

SQL Server 2019 CTP的第一版于9月24日发布,可以说它充满了各种改进和新功能(其中许多可以在Azure SQL数据库的预览表单中找到)。 我有一个难得的机会较早地了解了这一点,这使我能够甚至从表面上扩大对变化的理解。 您还可以阅读SQL Server团队最新出版物更新的文档

在不赘述的情况下,我将讨论以下新的内核功能:性能,故障排除,安全性,可用性和开发。 目前,我比其他人有更多的细节,其中一些已经准备发布。 我将返回本节以及许多其他文章和文档,并进行发布。 我赶紧通知您,这不是全面的回顾,只是我设法“接触”到CTP 2.0的部分功能。 还有很多要讨论的。

性能表现


表变量:延迟计划的建立


表变量的信誉不是很好,主要是在成本估算领域。 默认情况下,SQL Server假定一个表变量只能包含一行,这有时会导致计划选择不充分,因为该变量将包含更多行。 OPTION(RECOMPILE)通常用作解决方法,但是这需要更改代码,并且相对于资源而言,每次执行重建都是浪费的,而行数通常是相同的。 为了模拟重建,引入了跟踪标志2453 ,但是它也需要使用该标志进行启动,并且仅在行中发生重大变化时才起作用。

在兼容性级别150,如果存在表变量并且直到表变量被填充一次才构建查询计划,则执行延迟构造。 费用将基于表变量首次使用的结果进行估算,而无需进行进一步更改。 这是在为了获得准确成本而进行的持续重建与完全没有以恒定成本1进行重建之间的折衷方案。如果行数保持相对恒定,则这是一个很好的指标(如果行数超过1则更好),但如果行数差异很大。

我在最近的文章“ 表格变量:SQL Server中的延迟生成”中介绍了更深入的分析,而Brent Ozar在“ 快速表格变量(和新参数分析问题)”中也谈到了这一点。

字符串模式下的内存分配反馈


SQL Server 2017具有批处理内存分配反馈,在此处进行了详细描述。 本质上,对于与包含批处理模式语句的查询计划相关联的任何内存分配,SQL Server都会评估查询使用的内存并将其与请求的内存进行比较。 如果请求的内存太小或太大,这将导致tempdb耗尽或浪费内存,那么在下一次启动时,将调整为相应查询计划分配的内存。 此行为将减少分配的卷并扩展并发,或者增加并发以提高性能。

现在,在兼容级别150下,对于字符串模式的查询,我们得到相同的行为。如果查询被迫将数据合并到磁盘,则对于后续启动,分配的内存将增加。 如果在请求完成后,只需要分配一半的内存,那么对于后续请求,它将向下调整。 Bretn Ozar在他的“ 条件内存分配”一文中对此进行了更详细的描述。

批处理模式用于逐行存储


从SQL Server 2012开始,具有列索引的查询表受益于改进的批处理模式性能。 性能提高归功于查询处理器执行批处理而不是按行处理。 行也由包中的存储核心处理,这避免了并发交换语句。 保罗·怀特( @SQL_Kiwi )提醒我,如果您使用带有列存储的空表来进行批处理操作,那么处理后的行将通过一条不可见的语句收集到数据包中。 但是,此拐杖会否定从批处理中获得的任何改进。 有关此问题的一些信息在Stack Exchange答案中

在兼容性级别150下,即使没有列索引,在某些情况下,SQL Server 2019也会自动选择批处理模式作为中间立场。 您可能会想到,为什么不只创建一个列索引和一个帽子呢? 还是继续使用上述拐杖? 这种方法还扩展到具有行存储的传统对象,因为由于多种原因,列索引并非总是可行的,包括功能限制(例如触发器),高负载的更新或删除操作期间的开销以及缺乏第三方制造商的支持。 那个拐杖不会带来任何好处。
我创建了一个非常简单的表,该表具有一千万行和一个在整数列上的聚集索引,并运行以下查询:

SELECT sa5, sa2, SUM(i1), SUM(i2), COUNT(*) FROM dbo.FactTable WHERE i1 > 100000 GROUP BY sa5, sa2 ORDER BY sa5, sa2; 

该计划清楚地显示了聚集索引的搜索和并发性,但是没有任何关于列索引的信息(如SentryOne Plan Explorer所示):



但是,如果深入研究,您会发现几乎所有运算符都以批处理模式执行,甚至排序和标量计算也是如此:



您可以通过更改数据库配置或在查询中使用DISALLOW_BATCH_MODE提示符来保持较低的兼容性级别来禁用此功能:

 SELECTOPTION (USE HINT ('DISALLOW_BATCH_MODE')); 

在这种情况下,将出现一个附加的交换运算符,所有运算符均以逐行模式执行,查询执行时间几乎增加了两倍。



在某种程度上,您可以在图中看到它,但是在计划的详细信息树中,您还可以看到选择条件的影响,该选择条件在发生排序之前不能排除行:



选择批处理模式并不总是一个好步骤-决策算法中包含的启发式方法考虑了行数,建议的运算符类型以及批处理模式的预期收益。

APPROX_COUNT_DISTINCT


此新的聚合函数适用于数据仓库方案,等效于COUNT(DISTINCT())。 但是,新功能不是执行昂贵的排序来确定实际数量,而是依靠统计信息来获得相对准确的数据。 您需要了解误差在准确量的2%之内,并且在97%的高级分析案例中,这些是显示在指标上或用于快速评估的值。

在我的系统上,我创建了一个表,该表的整数列包含从100到1,000,000范围内的唯一值,行列包含从100到100,000范围内的唯一值。除第一个簇主键外,它没有索引。整数列。 这是在这些列上运行COUNT(DISTINCT())和APPROX_COUNT_DISTINCT()的结果,从中您可以看到细微的差异(但始终在2%以内):



如果存在内存限制,那么收益是巨大的,这适用于我们大多数人。 如果查看查询计划,在这种特殊情况下,您会看到哈希匹配运算符在内存消耗方面存在巨大差异:



请注意,如果您已经受到内存的限制,通常只会注意到显着的性能改进。 在我的系统上,由于新功能的高CPU使用率,执行持续了一点时间:



如果我有更大的表,更少的SQL Server可用内存,更高的并发性或以上各项的组合,则差异可能会更加明显。

在查询中使用兼容性级别的提示


您是否有一个特殊查询,在与现有数据库不同的特定兼容性级别下可以更好地工作? 现在,由于新的查询提示支持六种不同级别的兼容性以及五种用于估计元素数量的模型,因此这成为可能。 以下是可用的兼容性级别,示例语法和在每种情况下使用的兼容性级别模型。 查看这如何影响评分,甚至对于系统视图也是如此:



简而言之:不再需要记住跟踪标志,或者想知道是否需要担心查询优化器的TF 4199补丁是分发的还是被其他一些Service Pack取消了。 请注意,这些附加技巧最近也已在累积更新#10中为SQL Server 2017添加(请参阅Pedro Lopez的博客以获取详细信息)。 您可以使用以下命令查看所有可用的提示:

 SELECT name FROM sys.dm_exec_valid_use_hints; 

但是请不要忘记,提示是一种特殊的措施,它们通常适合摆脱困境,但是从长远来看,不应该计划使用它们,因为它们的行为可能随后续更新而改变。

故障排除


简化的默认配置文件


了解这种改进需要记住一些要点。 SQL Server 2014引入了DMV sys.dm_exec_query_profiles视图,该视图允许执行查询的用户收集有关查询所有部分中所有语句的诊断信息。 查询完成后,收集到的信息将变为可用,并允许您确定哪些操作员实际花费了主要资源以及原因。 任何未满足特定请求的用户都可以使用扩展的query_post_execution_showplan事件来接收包含STATISTICS XML或STATISTICS PROFILE语句的任何会话的所有数据,或所有会话的此数据,尽管此事件尤其会影响整体性能。

在Management Studio 2016中,添加了功能,使您可以基于从DMV收集的信息实时显示通过查询计划的数据流,这使其更强大地进行故障排除。 Plan Explorer还提供了可视化实时和回放模式下通过查询的数据的功能。

从SQL Server 2016 Service Pack 1(SP1)开始,您还可以使用跟踪标志7412或高级query_thread_profile属性启用轻量级版本来收集所有会话的数据,这使您可以立即获取有关任何会话的最新信息,而无需任何操作明确包括在内(特别是对性能产生不利影响的事物)。 Pedro Lopez博客对此进行了更详细的描述。

在SQL Server 2019中,默认情况下启用此功能,因此您无需运行任何具有扩展事件的会话,也无需在任何查询中使用任何跟踪标志和STATISTICS语句。 只需随时查看所有并发会话的DMV数据即可。 但是可以使用LIGHTWEIGHT_QUERY_PROFILING禁用此模式,但是,此语法在CTP 2.0中不起作用,并将在以后的版本中修复。

现在可以在克隆的数据库中使用群集的列索引统计信息


在当前版本的SQL Server中,克隆数据库时,仅使用来自群集列索引的对象的原始统计信息,不包括对表创建后的更新。 如果使用克隆来配置基于额定功率的查询和其他性能测试,则这些示例可能无法正常工作。 Parikshit Savyani 在本出版物中描述了局限性并提供了一个临时解决方案-在创建克隆之前,您需要创建一个脚本,该脚本对每个对象执行DBCC SHOW_STATISTICS ... WITH STATS_STREAM。 它很昂贵,当然,很容易忘记它。

在SQL Server 2019中,这些更新的统计信息将在克隆中自动提供,因此您可以测试各种查询方案并基于实际统计信息获得目标计划,而无需手动为所有表运行STATS_STREAM。

列存储的压缩预测


在当前版本中,sys.sp_estimate_data_compression_savings过程具有以下检查:

 if (@data_compression not in ('NONE', 'ROW', 'PAGE')) 

这意味着您可以检查行或页面的压缩(或查看删除当前压缩的结果)。 在SQL Server 2019中,此检查现在看起来像这样:

 if (@data_compression not in ('NONE', 'ROW', 'PAGE', 'COLUMNSTORE', 'COLUMNSTORE_ARCHIVE')) 

这是个好消息,因为它使您可以粗略地预测向没有索引的表中添加列索引的效果,或者将表或分区转换为更加压缩的列存储格式,而不必将表还原到另一个系统。 我有一个包含1000万行的表,为此我用五个参数分别执行了一个存储过程:

 EXEC sys.sp_estimate_data_compression_savings @schema_name = N'dbo', @object_name = N'FactTable', @index_id = NULL, @partition_number = NULL, @data_compression = N'NONE'; -- repeat for ROW, PAGE, COLUMNSTORE, COLUMNSTORE_ARCHIVE 

结果:



与其他类型的压缩一样,准确性完全取决于可用行和其余数据的代表性。 但是,这是获得可预期结果的一种非常有效的方法,没有太多困难。

获取页面信息的新功能


长期以来,DBCC PAGE和DBCC IND用于收集有关包含节,索引或表的页面的信息。 但是它们没有文档记录且不受支持,因此自动化与多个索引或页面关联的任务的解决方案可能很繁琐。

后来,出现了动态管理功能(DMF)sys.dm_db_database_page_allocations,该函数返回一个表示指定对象中所有页面的集合。 仍然没有文档记录,并且存在可能在大型表上变成实际问题的缺陷:即使要获取有关一页的信息,它也必须读取整个结构,这可能会非常昂贵。

在SQL Server 2019中,出现了另一个DMF-sys.dm_db_page_info。 它基本上返回所有页面信息,而没有DMF分发的开销。 但是,要在当前版本中使用该功能,您需要事先知道要查找的页面编号。 也许此步骤是有意采取的,因为 这是确保性能的唯一方法。 因此,如果您尝试标识索引或表中的所有页面,则仍然需要使用DMF分发。 在下一篇文章中,我将更详细地描述这个问题。

安全性


使用安全环境的永久加密(安全区)


目前,永久加密通过在过程的每一端进行加密/解密来保护传输和存储期间的敏感数据。 不幸的是,这在处理数据时通常会导致严重的限制,例如无法执行计算和过滤,因此您必须将整个数据集传输到客户端以执行范围搜索。

安全环境(安全区)是内存的受保护区域,可以在其中委派此类计算和筛选(Windows使用基于虚拟化的安全性 )-数据在内核中保持加密状态,但可以在安全环境中安全地解密或加密。 您只需要使用SSMS将ENCLAVE_COMPUTATIONS参数添加到主键,例如,通过选中“允许在安全环境中进行计算”框即可:



与以前的方法相比,现在您可以几乎立即对数据进行加密(在该方法中,向导,Set-SqlColumnEncyption cmdlet或您的应用程序将必须从数据库中完全获取整个集合,对其进行加密,然后将其发送回去):

 ALTER TABLE dbo.Patients ALTER COLUMN SSN char(9) -- currently not encrypted! ENCRYPTED WITH ( COLUMN_ENCRYPTION_KEY = ColumnEncryptionKeyName, ENCRYPTION_TYPE = Randomized, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256' ) NOT NULL; 

我认为对于许多组织来说,这一改进将是主要新闻,但是在当前的CTP中,其中一些子系统仍在改进中,因此默认情况下将其关闭,但是您可以在此处了解如何打开它们。

配置管理器中的证书管理


管理SSL和TLS证书一直很麻烦,许多人被迫做繁琐的工作来创建自己的脚本来部署和维护企业证书。 更新的SQL Server 2019 Configuration Manager将帮助您快速查看和验证任何实例的证书,查找即将到期的证书以及在可用性组中的所有复制或故障转移群集实例中的所有节点之间同步证书部署。

我没有尝试所有这些操作,但是如果管理来自SQL Server 2019 Configuration Manager,则它们应适用于SQL Server的早期版本。

内置数据分类和审核


SQL Server开发团队增加了对SSMS 17.5中的数据进行分类的功能,使您可以识别可能包含敏感信息或与各种标准(当然是HIPAA,SOX,PCI和GDPR)相抵触的任何列。 该向导使用一种算法,该算法提供应该引起问题的列,但是您可以通过从列表中删除这些列来调整其语句,也可以添加自己的列。 为了存储分类,使用了高级属性。 内置的SSMS报告使用相同的信息来显示其数据。 在报告之外,这些属性不是很明显。

SQL Server 2019引入了针对此元数据的新语句,该语句已在Azure SQL数据库中提供,并称为ADD SENSITIVITY CLASSIFICATION。 它允许您执行与SSMS中的向导相同的操作,但是信息不再存储在扩展属性中,并且对该数据的任何访问都将在审核中自动显示为新的XML列data_sensitiveivity_information。 它包含在审核期间受影响的所有类型的信息。

举个简单的例子,假设我有一个外部承包商的表格:

 CREATE TABLE dbo.Contractors ( FirstName sysname, LastName sysname, SSN char(9), HourlyRate decimal(6,2) ); 

从这种结构来看,很明显,所有四个色谱柱都可能容易泄漏,或者只有少数人才能使用。 您可以在这里获得许可,但是至少您需要关注它们。 因此,我们可以用不同的方式对这些列进行分类:

 ADD SENSITIVITY CLASSIFICATION TO dbo.Contractors.FirstName, dbo.Contractors.LastName WITH (LABEL = 'Confidential – GDPR', INFORMATION_TYPE = 'Personal Info'); ADD SENSITIVITY CLASSIFICATION TO dbo.Contractors.SSN WITH (LABEL = 'Highly Confidential', INFORMATION_TYPE = 'National ID'); ADD SENSITIVITY CLASSIFICATION TO dbo.Contractors.HourlyRate WITH (LABEL = 'Highly Confidential', INFORMATION_TYPE = 'Financial'); 

现在,您无需查看sys.extended_properties,而可以在sys.sensitiveivity_classifications中看到它们:



而且,如果我们对此表进行审核抽样(或DML),则无需专门更改任何内容; 创建分类后, SELECT *将在审计日志中的新列data_sensitiveivity_information中记录此类信息的记录:

 <sensitivity_attributes> <sensitivity_attribute label="Confidential - GDPR" information_type="Personal Info" /> <sensitivity_attribute label="Highly Confidential" information_type="National ID" /> <sensitivity_attribute label="Highly Confidential" information_type="Financial" /> </sensitivity_attributes> 

当然,这并不能解决所有符合标准的问题,但可以带来真正的优势。 使用向导自动识别列并将sp_addextendedproperty调用转换为ADD SENSITIVITY CLASSIFICATION命令可以大大简化符合标准的任务。 稍后,我将为此撰写另一篇文章。

您还可以基于元数据中的标签自动创建(或更新)权限-创建动态SQL脚本,禁止访问所有机密(GDPR)列,这将允许您管理用户,组或角色b。 以后我会在这个问题上进行研究。

有空


实时可再生指数创建


在SQL Server 2017中,可以实时暂停和恢复重建索引,如果您需要更改使用的处理器数量,从出现故障后暂停的那一刻起继续运行,或者只是缩小服务窗口之间的间隔,这将非常有用。 我在上一篇文章中谈到了此功能。

在SQL Server 2019中,您可以使用相同的语法来创建实时索引,暂停和继续以及限制执行时间(设置暂停时间):

 CREATE INDEX foo ON dbo.bar(blat) WITH (ONLINE = ON, RESUMABLE = ON, MAX_DURATION = 10 MINUTES); 

如果此查询的工作时间太长,则要暂停,您可以在另一个会话中运行ALTER INDEX(即使该索引实际上还不存在):

 ALTER INDEX foo ON dbo.bar PAUSE; 

在当前版本中,不能像重建那样降低更新期间的并行度。 尝试减少DOP时:

 ALTER INDEX foo ON dbo.bar RESUME WITH (MAXDOP = 2); 

我们得到以下内容:

 Msg 10666, Level 16, State 1, Line 3 Cannot resume index build as required DOP 4 (DOP operation was started with) is not available. Please ensure sufficient DOP is available or abort existing index operation and try again. The statement has been terminated. 

实际上,如果您尝试执行此操作,然后在不使用其他参数的情况下执行命令,则至少在当前版本中,您将得到相同的错误。 我认为更新尝试已记录在某处,系统希望再次使用它。 要继续,您必须指定正确(或更高)的DOP值:

 ALTER INDEX foo ON dbo.bar RESUME WITH (MAXDOP = 4); 

明确说明:恢复暂停的索引创建时可以增加DOP,但不能降低DOP。

所有这一切的另一个好处是,您可以使用新数据库的ELEVATE_ONLINE和ELEVATE_RESUMABLE子句将实时创建和/或续订索引配置为默认模式。

实时创建/重建集群列索引


除了创建可再生索引之外,我们还获得了实时创建或重建集群列索引的机会。 这是一项重大更改,它使您不再浪费服务窗口的时间来维护此类索引,或者(为了更加确定)将索引从基于行的索引转换为逐列的索引:

 CREATE TABLE dbo.splunge ( id int NOT NULL ); GO CREATE UNIQUE CLUSTERED INDEX PK_Splunge ON dbo.splunge(id); GO CREATE CLUSTERED COLUMNSTORE INDEX PK_Splunge ON dbo.splunge WITH (DROP_EXISTING = ON, ONLINE = ON); 

一个警告:如果实时创建了一个现有的传统聚簇索引,那么只有在这种模式下,它才能转换为聚簇列索引。如果它是主键的一部分,则内置还是不内置...

 CREATE TABLE dbo.splunge ( id int NOT NULL CONSTRAINT PK_Splunge PRIMARY KEY CLUSTERED (id) ); GO -- or after the fact -- ALTER TABLE dbo.splunge ADD CONSTRAINT PK_Splunge PRIMARY KEY CLUSTERED(id); 

我们收到以下错误:

 Msg 1907, Level 16 Cannot recreate index 'PK_Splunge'. The new index definition does not match the constraint being enforced by the existing index. 

您必须首先删除约束才能将其转换为集群列索引,但是这两个操作都可以实时执行:

 ALTER TABLE dbo.splunge DROP CONSTRAINT PK_Splunge WITH (ONLINE = ON); GO CREATE CLUSTERED COLUMNSTORE INDEX PK_Splunge ON dbo.splunge WITH (ONLINE = ON); 

这行得通,但是与将主键实现为唯一的聚集索引相比,大表可能需要更长的时间。我不确定这是故意限制还是仅是当前CTP的限制。

将复制连接从辅助服务器重定向到主服务器

此功能使您无需侦听即可配置重定向,因此即使直接在连接字符串中指定了辅助服务器,也可以将连接切换到主服务器。当群集技术不支持侦听,使用不带群集的AG或在具有多个子网的方案中存在复杂的重定向方案时,可以使用此功能。例如,这将防止连接尝试以只读模式(和失败)尝试编写用于复制的操作。

发展历程


图的其他功能


图形关系现在支持使用MERGE谓词的节点或边界表的MERGE语句;现在,一个操作员可以更新现有的边或插入新的边。新的边缘限制使您可以确定边缘可以连接的节点。

Utf-8


SQL Server 2012通过设置后缀_SC的名称(例如Latin1_General_100_CI_AI_SC)以使用Unicode列(nchar / nvarchar)来设置排序,从而增加了对UTF-16和其他字符的支持。在SQL Server 2017中,您可以使用诸如BCPBULK INSERT之类的工具将UTF-8数据导入和导出至这些列

在SQL Server 2019中,有新的排序规则选项可支持以原始形式强制保留UTF-8数据。因此,您可以使用带有后缀_SC_UTF8的新排序规则(例如Latin1_General_100_CI_AI_SC_UTF8)轻松创建char或varchar列并正确存储UTF-8数据。这可以帮助提高与外部应用程序和DBMS的兼容性,而无需花费处理和存储nvarchar的成本。

我发现的复活节彩蛋


据我所记得,SQL Server用户抱怨这条模糊的错误消息:

 Msg 8152 String or binary data would be truncated. 

在我尝试过的CTP版本中,发现了一条有趣的错误消息,该消息以前没有出现过:

 Msg 2628 String or binary data would be truncated in table '%.*ls', column '%.*ls'. Truncated value: '%.*ls' 

我认为这里不需要其他任何东西。这是一个很大的进步(尽管很晚了),并有望使许多人高兴。但是,此功能在CTP 2.0中将不可用。我只是给你一个机会,展望未来。布伦特·奥扎尔(Brent Ozar)列出了他在当前CTP中发现的所有新消息,并在他的sys.messages文章中对这些消息进行了一些有益的评论:找到更多功能

结论


SQL Server 2019提供了很好的附加功能,这些功能将有助于改进您最喜欢的关系数据库平台的工作,并且我还没有谈到很多更改。高效的内存,用于机器学习服务的集群,Linux上的复制和分布式事务,Kubernetes,用于Oracle / Teradata / MongoDB的连接器,同步AG复制已支持Java(类似于Python / R的实现),并且同样重要的是,这是一项新的飞跃,标题为“大数据集群”。要使用其中一些功能,必须使用此EAP表单进行注册

鲍勃·沃德(Bob Ward)即将出版的《 Linux上的Pro SQL Server》-包括使用Docker和Kubernetes的基于容器的部署,可能会为即将推出的其他许多事情提供一些线索。本出版物布伦特奥扎尔说,大约一个可能即将发生的校标量用户定义函数。

但是,即使在这第一个公开CTP中,几乎每个人都具有重要意义,我敦促您自己尝试!

Source: https://habr.com/ru/post/zh-CN424441/


All Articles