溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

CLR集成性能設(shè)計(jì)選擇的示例分析

發(fā)布時(shí)間:2022-01-05 15:44:59 來(lái)源:億速云 閱讀:117 作者:小新 欄目:編程語(yǔ)言

這篇文章將為大家詳細(xì)講解有關(guān)CLR集成性能設(shè)計(jì)選擇的示例分析,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

1.編譯過(guò)程

在編譯 SQL 表達(dá)式時(shí),如果遇到對(duì)托管例程的引用,則生成 Microsoft 中間語(yǔ)言 (MSIL) 存根。該存根包含的代碼用于將例程參數(shù)從 SQL Server 封送到 CLR、調(diào)用函數(shù)并返回結(jié)果。該“粘附”代碼基于參數(shù)類型和參數(shù)方向(向內(nèi)、向外或引用)。粘附代碼支持特定于類型的優(yōu)化,并確保有效地強(qiáng)制實(shí)現(xiàn) SQL Server 語(yǔ)義,例如為 Null 性、約束方面、按值和標(biāo)準(zhǔn)異常處理。通過(guò)為確切類型的參數(shù)生成代碼,可以避免跨調(diào)用邊界的類型強(qiáng)制或包裝對(duì)象創(chuàng)建開(kāi)銷(稱為“裝箱”)。隨后,使用 CLR 的 JIT(實(shí)時(shí))編譯服務(wù)將生成的存根編譯為本機(jī)代碼,并針對(duì) SQL Server 執(zhí)行所在的特定硬件體系結(jié)構(gòu)進(jìn)行優(yōu)化。JIT 服務(wù)是在方法級(jí)別調(diào)用的,并允許 SQL Server 宿主環(huán)境創(chuàng)建一個(gè)跨 SQL Server 和 CLR 執(zhí)行的編譯單元。編譯存根之后,生成的函數(shù)指針即成為函數(shù)的運(yùn)行時(shí)實(shí)現(xiàn)。此代碼生成方法確保不會(huì)發(fā)生與運(yùn)行時(shí)反射或元數(shù)據(jù)訪問(wèn)相關(guān)的其他調(diào)用開(kāi)銷。

在 SQL Server 和 CLR 之間快速轉(zhuǎn)換
編譯過(guò)程生成的函數(shù)指針可以在運(yùn)行時(shí)通過(guò)本機(jī)代碼調(diào)用。對(duì)于標(biāo)量值用戶定義函數(shù),可基于每行調(diào)用此函數(shù)。為***程度地降低在 SQL Server 和 CLR 之間轉(zhuǎn)換的成本,包含任何托管調(diào)用的語(yǔ)句都具有一個(gè)標(biāo)識(shí)目標(biāo)應(yīng)用程序域的啟動(dòng)步驟。該標(biāo)識(shí)步驟減少每行的轉(zhuǎn)換成本。

2.性能注意事項(xiàng)
 
以下內(nèi)容概述了 SQL Server 中特定于CLR集成性能的注意事項(xiàng)。有關(guān)更多詳細(xì)信息,請(qǐng)參閱 MSDN 網(wǎng)站上的“Using CLR Integration in SQL Server 2005”(在 SQL Server 2005 中使用 CLR 集成)。有關(guān)托管代碼性能的常規(guī)信息,請(qǐng)參閱 MSDN 網(wǎng)站上的“Improving .NET Application Performance and Scalability”(提高 .NET 應(yīng)用程序的性能和可擴(kuò)展性)。

3.用戶定義函數(shù)

相較于 Transact-SQL 用戶定義函數(shù),CLR 函數(shù)可以從更快的調(diào)用路徑中受益。此外,同 Transact-SQL 相比,托管代碼在過(guò)程代碼、計(jì)算和字符串操作方面具有決定性性能優(yōu)勢(shì)。需要大量計(jì)算和不執(zhí)行數(shù)據(jù)訪問(wèn)的 CLR 函數(shù)采用托管代碼編寫(xiě)時(shí)效果更好。但是與CLR集成性能相比,Transact-SQL 函數(shù)的確可以更有效地執(zhí)行數(shù)據(jù)訪問(wèn)。

4.用戶定義聚合

托管代碼的性能大大優(yōu)于基于游標(biāo)的聚合。托管代碼的執(zhí)行速度通常稍慢于內(nèi)置 SQL Server 聚合函數(shù)的執(zhí)行速度。如果存在本機(jī)內(nèi)置聚合函數(shù),建議您使用該函數(shù)。對(duì)于所需聚合不受本機(jī)支持的情況,出于性能原因,請(qǐng)考慮使用 CLR 用戶定義聚合,而不是基于游標(biāo)的實(shí)現(xiàn)。

5.流式表值函數(shù)

應(yīng)用程序通常需要返回一個(gè)表作為調(diào)用函數(shù)的結(jié)果。示例包括從文件讀取表格格式數(shù)據(jù)作為導(dǎo)入操作的一部分,并將逗號(hào)分隔值轉(zhuǎn)換為關(guān)系表示形式。通常,您可以通過(guò)在調(diào)用方使用結(jié)果表之前具體化和填充此結(jié)果表來(lái)實(shí)現(xiàn)此目的。CLR 與 SQL Server 的集成引入了一種名為流式表值函數(shù) (STVF) 的新擴(kuò)展性機(jī)制。托管 STVF 的性能優(yōu)于可比擴(kuò)展存儲(chǔ)過(guò)程實(shí)現(xiàn)的性能。STVF 是返回 IEnumerable 接口的托管函數(shù)。IEnumerable 具有導(dǎo)航 STVF 返回的結(jié)果集的方法。當(dāng)調(diào)用 STVF 時(shí),返回的 IEnumerable 直接連接到查詢計(jì)劃。查詢計(jì)劃在需要提取行時(shí)調(diào)用 IEnumerable 方法。使用此迭代模型,結(jié)果在***行生成之后即可使用,而不需要等到整個(gè)表填充完。還可以極大地減少調(diào)用該函數(shù)而占用的內(nèi)存。

6.數(shù)組與游標(biāo)

當(dāng) Transact-SQL 游標(biāo)必須遍歷更容易表示為數(shù)組的數(shù)據(jù)時(shí),使用托管代碼可以顯著提高性能。

7.字符串?dāng)?shù)據(jù)

SQL Server 字符數(shù)據(jù)(如 varchar)在托管函數(shù)中可以是 SqlString 或 SqlChars 類型。SqlString 變量將整個(gè)值的實(shí)例創(chuàng)建到內(nèi)存中。SqlChars 變量提供可用于獲得更好性能和可擴(kuò)展性的流式接口,而無(wú)需將整個(gè)值的實(shí)例創(chuàng)建到內(nèi)存中。這對(duì)于大型對(duì)象 (LOB) 數(shù)據(jù)尤為重要。此外,還可以通過(guò) SqlXml.CreateReader() 返回的流式接口訪問(wèn)服務(wù)器 XML 數(shù)據(jù)。

8.CLR 與擴(kuò)展存儲(chǔ)過(guò)程

允許托管過(guò)程向客戶端回發(fā)結(jié)果集的 Microsoft.SqlServer.Server 應(yīng)用程序編程接口 (API) 的性能優(yōu)于擴(kuò)展存儲(chǔ)過(guò)程使用的開(kāi)放式數(shù)據(jù)服務(wù) (ODS) API。此外,System.Data.SqlServer API 支持 xml、varchar(max)、nvarchar(max) 和 varbinary(max) 等 SQL Server 2005 中引入的數(shù)據(jù)類型,但是尚未將 ODS API 擴(kuò)展為支持新的數(shù)據(jù)類型。

通過(guò)托管代碼,SQL Server 管理對(duì)內(nèi)存、線程和同步等資源的使用。這是因?yàn)楣_(kāi)這些資源的托管 API 是針對(duì) SQL Server 資源管理器實(shí)現(xiàn)的。相反,SQL Server 無(wú)法查看或控制擴(kuò)展存儲(chǔ)過(guò)程的資源使用情況。例如,如果擴(kuò)展存儲(chǔ)過(guò)程占用過(guò)多 CPU 或內(nèi)存資源,則無(wú)法通過(guò) SQL Server 檢測(cè)或控制此種情況。但是,SQL Server 可以使用托管代碼檢測(cè)到給定線程已有很長(zhǎng)一段時(shí)間未生成結(jié)果,并強(qiáng)制該任務(wù)生成以便安排其他工作。因此,使用托管代碼可以提高可擴(kuò)展性,并改善系統(tǒng)資源使用情況。托管代碼可能帶來(lái)維護(hù)執(zhí)行環(huán)境和執(zhí)行安全檢查所需的額外開(kāi)銷。例如,當(dāng)在 SQL Server 內(nèi)運(yùn)行并需要執(zhí)行從托管代碼到本機(jī)代碼的大量轉(zhuǎn)換時(shí),可能會(huì)發(fā)生此種情況(因?yàn)樵谕泄艽a和本機(jī)代碼之間來(lái)回轉(zhuǎn)換時(shí),SQL Server 需要對(duì)特定于線程的設(shè)置進(jìn)行額外維護(hù))。因此,對(duì)于在托管代碼和本機(jī)代碼之間進(jìn)行頻繁轉(zhuǎn)換的情況,擴(kuò)展存儲(chǔ)過(guò)程的性能大大優(yōu)于在 SQL Server 內(nèi)運(yùn)行的托管代碼的性能。

注意:
建議您不要開(kāi)發(fā)新的擴(kuò)展存儲(chǔ)過(guò)程,因?yàn)橐巡煌扑]使用此功能。

9.用戶定義類型的本機(jī)序列化

用戶定義類型 (UDT) 是作為標(biāo)量類型系統(tǒng)的擴(kuò)展性機(jī)制設(shè)計(jì)的。SQL Server 實(shí)現(xiàn)稱為 Format.Native 的 UDT 序列化格式。在編譯期間,檢查該類型的結(jié)構(gòu)以便生成針對(duì)該特定類型定義自定義的 MSIL。本機(jī)序列化是針對(duì) SQL Server 的默認(rèn)實(shí)現(xiàn)。用戶定義序列化調(diào)用由類型作者定義的方法以執(zhí)行序列化。應(yīng)盡可能使用 Format.Native 序列化以便獲取***性能。

10.可比 UDT 的規(guī)范化

關(guān)系操作(例如對(duì) UDT 進(jìn)行排序和比較)是針對(duì)值的二進(jìn)制表示形式直接執(zhí)行的。通過(guò)在磁盤(pán)上存儲(chǔ) UDT 狀態(tài)的規(guī)范化(二進(jìn)制排序)表示形式可以實(shí)現(xiàn)此目的。規(guī)范化具有兩個(gè)優(yōu)點(diǎn):避免構(gòu)造類型實(shí)例和方法調(diào)用開(kāi)銷,進(jìn)而極大地降低了比較操作的成本;為 UDT 創(chuàng)建二進(jìn)制域,支持構(gòu)造直方圖、索引以及該類型的值的直方圖。因此,規(guī)范化 UDT 的性能配置文件類似于未涉及方法調(diào)用的操作的本機(jī)內(nèi)置類型性能配置文件。

11.可擴(kuò)展內(nèi)存使用量

為了在 SQL Server 中很好地執(zhí)行和調(diào)整托管垃圾回收,請(qǐng)避免使用大型單一分配。大小大于 88 千字節(jié) (KB) 的分配將被放置到大對(duì)象堆,這將導(dǎo)致垃圾回收的性能和調(diào)整結(jié)果遠(yuǎn)不如多個(gè)較小分配的性能和調(diào)整結(jié)果。例如,如果需要分配一個(gè)大型多維數(shù)組,***分配一個(gè)交錯(cuò)(分散)數(shù)組。

關(guān)于“CLR集成性能設(shè)計(jì)選擇的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

clr
AI