SQL Server 2019 第一個公共CTP版的新特性

翻譯自:node

https://www.mssqltips.com/sqlservertip/5710/whats-new-in-the-first-public-ctp-of-sql-server-2019/web


問題算法

SQL Server 2019的第一個公共CTP版已經發布,充滿了加強和新特性(其中不少也能夠在預覽形式Azure SQL Database裏找到)。我以前有深刻了解過,容許我分享一下個人經驗。你也能夠查看SQL Server團隊最新的博文更新的官方技術文檔sql


解決方案數據庫

我將討論一些新的引擎特性,分爲下五個方面:性能、問題定位、安全、可用性和開發。此次,對於有些特性我有更詳細的內容,事實上已經寫了完整的博文詳述幾個。當更多的文檔和文章可用時,我將回頭更新這些部分。放心,這不是一個詳盡的列表,只是直到CTP 2.0版我已瞭解的內容。還會有更多內容到來。瀏覽器




性能安全


表變量延遲編譯(Table variable deferred compilation)服務器

表變量名聲有點很差,大多由於預估。默認,SQL Server預計只有一行會出如今表變量中,當實際有多行時會致使某些有趣的計劃選擇。避免這種狀況的典型變通方案是使用OPTION (RECOMPILE),但這須要修改代碼,當行數一般相同時單次重編譯很浪費時間。引入了跟蹤標誌2453來模擬重編譯行爲,可是須要運行在一個跟蹤標誌下,只有當發現又很明顯行數變化時纔會發生。架構

在兼容級別150,當表變量調用時你能夠延遲編譯,意思是,直到表變量被填充一次纔會構建一個計劃。預估將基於表變量的第一次使用,再次以後將沒有重編譯發生。這是一個在一直重編譯以得到實際每次預估,和從不重編譯一直預估爲1之間的折中。 若是你的行數保持相對穩定就很好,而且這個數遠遠大於1就更好,但若是這個數大幅波動就沒什麼用。併發

在最近發表的博文中,我深刻研究了該功能,SQL Server中的表變量延遲編譯,Brent Ozar在更快的表變量和新的參數嗅探問題也談到了它。


行模式內存授予反饋(Row mode memory grant feedback)

SQL Server 2017引入了批模式內存授予反饋,在這裏有詳細描述。本質上,對於任何與執行計劃有關的內存授予牽涉到批模式操做者,SQL Server會預估查詢的內存使用,並將它與請求內存相比較。若是請求的內存過低或過高,致使溢出或浪費內存,它會在下次運行的時候調整與執行計劃相關的內存授予。這要麼會減小授予以容許更高併發量,要麼增長授予以提升性能。

如今在兼容級別150下,對於行模式查詢咱們也得到了該行爲。若是一個查詢被發現須要訪問磁盤,對於後續的執行將會增長內存授予。若是查詢的實際內存使用少於內存授予的一半,後續授予請求將會更低。Brent Ozar在這篇文章適當的內存授予中講得更細。


基於行存儲的批模式(Batch mode over rowstore)

自從SQL Server 2012,對帶有列存儲索引的表查詢在批模式的性能加強中收益。性能提高是因爲相對一行行執行,查詢處理器執行批處理。數據行能夠在存儲引擎上面以批的形式存儲,能夠避免並行交換算子。Paul White(Twitter帳號@SQL_Kiwi)提醒我若是你使用一個空的列存儲表能夠執行批模式操做,存儲的行由不可見的操做符彙集成批。然而,這個黑 客行爲會取消從批模式處理得到的任何提高。在Stack Exchange的回答中有些信息。

在兼容級別150下,SQL Server 2019會在特定的熱點案例中自動選擇批模式,即便沒有出現列存儲索引。你會想,爲何不僅建立一個列存儲索引並使用它?或者使用上面提到的黑 客行爲?這種狀況擴展到傳統的行存儲對象,由於列存儲索引不老是可能的,因爲大量緣由,包括缺少特性支持(例如觸發器),大量的更新刪除負載下,或者缺少第三方支持。上面提到的黑 客行爲只是一個壞消息。

我建立了一個1千萬行的簡單表,在整型列上建立了一個單一彙集索引,而後運行以下查詢:

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

這個查詢清晰的顯示了一個彙集索引查找和並行,可是沒有任何列存儲索引的跡象(顯示在SentryOne執行計劃瀏覽器,一個免費查詢調優工具):

clip_image002

若是你深刻研究,會發現幾乎全部的操做符都以批模式運行,甚至排序和標量計算:

clip_image004

你能夠經過保持在一個更低的兼容級別上、經過修改數據庫範圍配置(在未來的CTP版本會到來),或經過使用DISALLOW_BATCH_MODE查詢提示來禁止該功能:

SELECT … OPTION (USE HINT ('DISALLOW_BATCH_MODE'));

在這個案例中以上查詢計劃有一個額外的交換運算符,全部的運算符以行模式執行,該查詢花費了三倍時間去運行:

clip_image006

你能夠在這個圖上看到,可是在執行計劃樹的詳細信息裏,你也能夠看到謂詞直到排序後纔會消除行:

clip_image008

批模式的選擇不老是必殺器。而是與行計數的決定,操做符相關的類型和批模式期待收益有關。


APPROX_COUNT_DISTINCT

新的聚合函數爲數據倉庫場景設計,等價於COUNT(DISTINCT())。替代執行昂貴的排序去重操做以肯定實際行數,它依賴於統計信息來獲取相對真實的數據。你會發現差距是實際計數的2%,97%的時間,一般用於高級別分析,值用於填充一個報表,或快速預估。

我建立了一個表,有一個值範圍在100到1000000之間的惟一值的整型列,和一個值範圍在100到100000之間的惟一值的字符串列。除了主要整型列上的彙集索引主鍵,沒有其餘索引。針對這些列的COUNT(DISTINCT())和APPROX_COUNT_DISTINCT()的比較結果,你能夠看到差別總在2%之內。

clip_image009

若是你是內存受限的,回報是巨大的,適用於大多數狀況。若是你這個案例中查看執行計劃,你會看到在哈希匹配操做符上內存佔用量的巨大差別:

clip_image011

注意:

若是你已是內存受限的,你只會看到重要的性能提高。在個人系統上,因爲更多CPU被新的函數使用,運行時間稍微更長一些:

clip_image013

若是我有更大的表,更少的可用內存給到SQL Server,更高的併發量,或任何組合,結果頗有可能不同。


查詢做用域的兼容級別提示(Query-scoped compatibility level hints)

有一個查詢在與當前數據庫不一樣的兼容級別下運行得更好?如今你可使用新的查詢提示支持六個不一樣的兼容級別和五個不一樣的基數預估模式。如下顯示了在每一個案例中使用的可用兼容級別,示例語法和CE模式。你能夠看到它如何影響預估,甚至對於系統目錄視圖:

clip_image015

長話短說:再也不須要記錄跟蹤標誌,或懷疑是否仍然須要擔憂在TF 4199下你的優化修復被覆蓋,或被某些服務包或累積更新包所消除。注意,這些額外的提示當前也被添加到SQL Server 2017累積更新10中(查看Pedro Lopes的博文查看更多詳細信息)。你也能夠看到全部可用提示:

SELECT name FROM sys.dm_exec_valid_use_hints;

但請一直記住提示是最後的依靠。它們讓你擺脫困境,可是你不能長期讓你的代碼像那樣,由於隨着以後的更新行爲會改變。




問題定位


默認開啓輕量級跟蹤(Lightweight profiling on by default)

這個加強須要一點背景知識。SQL Server 2014引入了DMV sys.dm_exec_query_profiles,容許用戶運行查詢,同時收集查詢執行期間全部操做符的診斷信息。在查詢完成後,這個信息能夠被用來肯定哪一個操做符實際作了最多工做而且爲何。沒有運行那個特定查詢的任何用戶,仍然能夠對任何會話啓用STATISTICS XML或STATISTICS PROFILE,或者對於全部會話經過query_post_execution_showplan擴展事件(經過該事件會對總體性能帶來潛在的巨大壓力)來得到這個數據的解析。

SSMS 2016添加了功能基於從DMV收集的信息經過執行計劃實時顯示數據移動,它對於問題定位很是有用。執行計劃瀏覽器也提供了對於查詢執行期間可視化數據的實時和重放能力。

從SQL Server 2016 SP1開始,你也能夠對於全部會話啓用輕量版本的數據收集,經過使用跟蹤標誌7412或者query_thread_profile擴展事件,以便你能夠當即得到任何會話的確切信息而不用在他們的會話中顯示啓用任何東西(特別是負面影響性能的東西)。與此有關的更多信息在Pedro Lopes的博文中

在SQL Server 2019,這個進程跟蹤默認被啓用。因此你不須要運行一個特定擴展事件會話,或者任何跟蹤標誌,或者在任何獨立查詢開啓STATISTICS選項;你只能對併發會話在任什麼時候候從DMV查看數據。你可使用一個新的數據庫範圍配置叫LIGHTWEIGHT_QUERY_PROFILING來關閉它,但該語法不能工做在CTP 2.0(這將會被未來的CTP修復)。


彙集列存儲索引統計信息在克隆數據庫時可用(Clustered Columnstore Index Statistics Available in Clone Databases)

在當前版本的SQL Server,克隆數據庫只會從彙集列存儲索引帶來原始統計對象,忽略任何在建立後對該表所作的任何更新。若是你對依賴於基數預估的查詢調優和其餘性能測試使用克隆,這些案例可能無效。Parikshit Savjani在這篇博文描述了限制,並提供了一個工做區:在開始克隆前,生成了一個針對每一個對象運行DBCC SHOW_STATISTICS…WITH STATS_STREAM的腳本。這個成本很高,徹底容易忘記。

在SQL Server 2019,這些更新的統計信息也只能在克隆時自動可用,所以你能夠測試不一樣的查詢場景,並基於真實統計信息得到可靠的計劃,不用對全部表運行STATS_STREAM。


對於列存儲的壓縮預估(Compression estimates for Columnstore)

在當前版本,存儲過程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'))

這是個好消息,由於它容許你粗略預估添加一個列存儲索引到一個表的影響,或者轉換一個表或分區到一個更激進的列存儲格式,不用存儲表到另外一個系統並實際嘗試它。在個人系統上有一個1千萬行的表,提供五個參數運行該存儲過程:

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

結果:

clip_image017

如同其餘壓縮類型,精確性依賴於行取樣,和這些數據在其餘數據中的表明性。固然,這是一個猜猜看的很好方式而不用精準數據。


得到頁信息的新函數(New function to retrieve page info)

DBCC PAGE和DBCC IND長期用於收集包含分區、索引或表的信息。但它們是未公開的和不支持的命令。關於涉及多個索引或頁的問題對於自動化解決方案是至關乏味的。

隨着sys.dm_db_database_page_allocations的到來,DMF返回特定對象的全部頁的一個集合。仍然是未公開的,該功能展現了在大表上的實際問題--謂詞下推:即便得到單頁的信息,也得讀取整個結構,這多是頗爲忌諱的。

SQL Server 2019引入了另外一個DMF sys.dm_db_page_info。它基本返回了一頁上的全部信息,沒有分配DMF的開銷。在當前版本,你得已經知道使用這個函數的頁號。這多是有意的,由於這樣是惟一確保性能的方法。所以若是你嘗試肯定一個索引或表裏的全部頁,你仍然須要使用分配DMF。以後我會寫些關於這個函數的博文。




安全


始終使用安全包加密敏感數據(Always Encrypted using Secure Enclaves)

今天,在傳輸中始終使用安全包加密敏感數據,和在每一個進程端在內存中加密和解密。不幸的是,這一般會引入關鍵的處理約束,這樣不能執行運算和過濾。意味着爲了執行一個範圍查找,整個數據集得被髮送。

一個安全包是一個保護的內存區域,在哪裏運算和過濾被委託(在Windows中,這使用基於虛擬化的安全)。數據在引擎中保持加密,可是在安全包中能夠被安全加密或解密。你只須要添加ENCLAVE_COMPUTATIONS選項到主祕鑰,你能夠再SSMS中勾選「Allow enclave computations」複選框:

clip_image018

與老方法相比(經過嚮導,或者Set-SqlColumnEncyption命令,或應用程序,須要將數據庫的全部數據徹底移出、加密、而後發送回數據庫),如今你幾乎能夠當即加密數據:

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版某些優化仍舊是很棒的,而它們默認沒啓用。但在這篇文章啓用豐富的運算你能夠了解到如何開啓。


在配置管理中的證書管理(Certificate Management in Configuration Manager)

管理SSL和TLS證書一直是一個痛點,不少人不得不執行冗長乏味的工做和自制的腳本,在企業中部署和維護證書。隨着SQL Server 2019配置管理器的功能更新,容許你快速查看和驗證任何實例的證書,找出即將過時的證書,在AG中跨多個副本(從一個地方:主副本)、或者FCI中的全部節點(從一個地方:活躍節點)同步部署證書。

我尚未嘗試全部這些操做,可是它們應該能對舊版的SQL Server起做用,只要從SQL Server 2019版的SQL Server配置管理器來執行。


內置數據分類和審計(Built-In Data Classification and Auditing)

在SSMS 17.5,SQL Server團隊在SSMS中添加了分類數據的功能,你能夠識別可能包含敏感信息的列,或者可能不遵照各類標準(HIPAA、SOX、PCI和GDPR)。該向導使用一個算法,對於它認爲可能致使規範性問題的列給出建議,但你能夠本身添加、調整它的建議,並從列表消除任何列。使用擴展屬性存儲這些分類;基於SSMS的報表使用相同的信息來顯示這些被識別的列。報表外,這些屬性不可見。

在SQL Server 2019對於該元數據有個新命令,在Azure SQL Database也有,叫作ADD SENSITIVITY CLASSIFICATION。這容許你像SSMS嚮導同樣作一樣的事情,可是信息再也不存儲爲擴展屬性,任何對數據的訪問自動以新的XML列data_sensitivity_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.sensitivity_classifications的元數據:

clip_image020

若是你對該表審計SELECT或DML,你沒必要修改審計;建立了分類後一個SELECT *將在審計日誌中產生新的data_sensitivity_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命令,能夠很好的聽從規範性。以後我會寫更多關於此的博文。

你也能夠基於標籤元數據自動或更新權限。對一個用戶、組或徹底可管理的角色,建立一個禁止訪問全部Confidential – GDPR列的動態SQL語句。以後我會展開來說。




可用性


可恢復在線索引建立(Resumable online index creation)

SQL Server 2017引入了暫停和恢復在線索引重建的功能,對於你想修改使用的CPU數頗有用,在一個故障轉移事件後繼續剩下的操做,或者只是填補維護窗口間的空白。以前的博文我已講到該特性,關於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,你只是不能減小。

另外一個額外的好處是,當使用新的數據庫範圍配置ELEVATE_ONLINE和ELEVATE_RESUMABLE時,默承認以對數據庫執行在線和可恢復索引操做。


彙集列存儲索引在線建立、重建(Online create / rebuild for Clustered Columnstore Indexes)

除了可恢復的在線索引建立,你也能夠在線建立或重建彙集列存儲索引(固然這也是可恢復的)。巨大改變是你再也不須要維護窗口來執行索引維護,一個更具說服力的案例:將行存儲轉換爲列存儲:

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版本的限制。


輔助副本到主副本鏈接重定向(Secondary to Primary Replica Connection Redirection)

該特性容許你不用監聽器配置重定向,所以即使輔助副本在鏈接串中顯式命名,你能夠切換鏈接到主副本。當你的羣集拓撲不支持監聽器,或者當你使用無羣集AG,或者在多子網場景下有一個複雜的重定向架構,你也可使用該特性。例如,這將阻止嘗試對一個只讀副本寫操做(失敗)的鏈接。




開發


圖加強(Graph enhancements)

圖關係如今對node或edge表支持使用MATCH謂詞的MERGE語句;如今一條語句能夠更新一個存在的edge或插入一個新的edge。一個新edge約束容許控制一個edge能夠鏈接那個node。


UTF-8

SQL Server 2012添加了對UTF-16的支持,經過將排序規則命名爲_sc後綴來增補字符,像Latin1_General_100_CI_AI_SC,對於使用Unicode列(nchar/nvarchar)。在SQL Server 2017,能夠以UTF-8格式導入和導出數據,經過BCPBULK INSERT來處理這些列。

在SQL Server 2019,有新的排序規則在SQL Server內本地支持存儲爲UTF-8數據。所以,你能夠適當的使用新的以_SC_UTF8後綴的排序規則建立char或varchar列存儲UTF-8數據,像Latin1_General_100_CI_AI_SC_UTF8。這能夠幫助提升擴展應用和其餘數據庫平臺和系統的兼容性,不用花費性能去存儲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副本最多可到5個支持Java(相似於Python/R的實現),最後一點,新的嘗試「Big Data Cluster」。這些新特性你須要填寫EAP表單得到。

Bob Ward即將出版的新書,Pro SQL Server on Linux – Including Container-Based Deployment with Docker and Kubernetes,會給你一些新線索。Brent Ozar的博文談到了對用戶自定義標量函數的即將到來的修復。

但即使是在第一個公共CTP版,這些特性都只是針對每一個人的,我鼓勵你本身作實驗,讓我知道你以爲怎樣。


接下來

閱讀更多關於SQL Server 2019的資源:

相關文章
相關標籤/搜索