Sql-Server
提高在 SQL Server 中將大型 xml 文件 (~300 MB) 轉換為關係表的性能
所以這就是我到目前為止所擁有的:
--Read xml content into a XML data type variable DECLARE @FileData XML SELECT @FileData = CONVERT(XML, BulkColumn) FROM OPENROWSET(BULK '\\file_path\test.xml', SINGLE_BLOB) AS x --Read from the XML variable to create Entity-Attribute-Value table SELECT N1.Id.value('@Id', 'varchar(50)') as Id , N1.Id.value('@Name', 'varchar(100)') as Name , N2.AttributeLongName.value('@AttributeName', 'varchar(100)') as AttributeName , N3.AttributeValue.value('.', 'varchar(MAX)') as AttributeValue FROM @FileData.nodes('/Data/Entities/Entity') as N1(Id) ---1st lvl Node contains the Entity cross apply Id.nodes('Attributes/Attribute') as N2(AttributeName) --2nd lvl Node contains AttributeName cross apply AttributeName.nodes('Values/Value') as N3(AttributeValue) --3rd lvl Node contains AttributeValue
此程式碼在針對 8 MB XML 文件(約 15 秒)執行時表現良好。但是,當我嘗試針對相同結構的 300 MB XML 文件執行它時,需要花費數小時。
這是否意味著 XQuery nodes() 方法不能線性擴展或擴展最差?
有沒有其他方法可以提高性能?
我又看了一遍,可以重現您的問題。嘗試添加
OPTION ( MAXDOP 1 )
到您的查詢中。在我的帶有 300MB 文件的測試台中,它在 1 分 42 秒內執行。未經提示的版本在我殺死它之前以 100% CPU 執行了 30 分鐘。你也可以看看OPENXML。人們經常說大型 XML 文件速度更快,在這種情況下似乎就是這樣。但是,您應該注意已知問題
OPENXML
(例如,可能佔用緩衝池的 1/8,是老式的 COM .dll,您必須呼叫sp_xml_removedocument
等)。一旦你研究了 的優缺點OPENXML
,你可以嘗試這樣的事情:DECLARE @FileData XML SELECT @FileData = BulkColumn FROM OPENROWSET(BULK 'd:\temp\temp.xml', SINGLE_BLOB) AS x DECLARE @hDoc int EXEC sp_xml_preparedocument @hDoc OUTPUT, @FileData SELECT * INTO #tmp FROM OPENXML( @hDoc, '/Data/Entities/Entity/Attributes/Attribute/Values/Value', 1 ) WITH ( Id VARCHAR(50) '../../../../@Id', Name VARCHAR(100) '../../../../@Name', AttributeName VARCHAR(100) '../../@AttributeName', AttributeValue VARCHAR(MAX) '.' ) EXEC sp_xml_removedocument @hDoc
老實說,由於這些問題,這些天我試圖避免它;當您剛剛減少 1/8 的緩衝池時,一個查詢更快有什麼意義?
最後,最快和最可擴展的方法(恕我直言)是 SSIS。對於與我的裝備中的上述方法相同的文件,此版本在大約 10 秒內執行。
SSIS XML 導入方法
創建一個包,添加一個數據流任務,添加一個 XML 源,然後添加每個表。我創建了一個與你的結構相同的 300MB 文件,它在大約 10 秒內載入,例如
顯然,您需要額外的時間來查詢已導入的表,但我認為這是一種更安全的方法。你甚至可以用多個包來擴展它。如果您在包裹方面需要更多幫助,請回帖。