[英]Speeding up inserting XML file into SQL Server table
我正在使用以下腳本使用Powershell將大型XML文件(3.5Gb)插入本地SQL Server表'files_index
中,因為該文件超出了SQL的2 GB限制。
表結構如下,然后是PowerShell腳本。 該文件包含大約5000000行,但是要花費很長的時間才能插入,盡管這樣做行之有效,但我正在尋找可以加快速度的任何方法(目前大約需要15分鍾)。
關於加快處理速度的任何建議,我都嘗試過增加批處理大小,但這似乎並沒有太大的區別,我不久前在stackoverflow上獲得了此powershell腳本,但我只是想簡化流程。 感謝您的協助或建議。
CREATE TABLE [dbo].[files_index]
(
[Product_ID] [int] NOT NULL,
[path] [varchar](100) NULL,
[Updated] [varchar](50) NULL,
[Quality] [varchar](50) NULL,
[Supplier_id] [int] NULL,
[Prod_ID] [varchar](100) NULL,
[Catid] [int] NULL,
[On_Market] [int] NULL,
[Model_Name] [varchar](250) NULL,
[Product_View] [varchar](250) NULL,
[HighPic] [varchar](250) NULL,
[HighPicSize] [int] NULL,
[HighPicWidth] [int] NULL,
[HighPicHeight] [int] NULL,
[Date_Added] [varchar](150) NULL,
CONSTRAINT [PK_files_index]
PRIMARY KEY CLUSTERED ([Product_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]
PowerShell腳本:
Set-ExecutionPolicy Unrestricted -scope LocalMachine
[String]$global:connectionString = "Data Source=Apps2\Apps2;Initial
Catalog=DTEDATA;Integrated Security=SSPI";
[System.Data.DataTable]$global:dt = New-Object System.Data.DataTable;
[System.Xml.XmlTextReader]$global:xmlReader = New-Object
System.Xml.XmlTextReader("C:\Scripts\icecat\files.index.xml");
[Int32]$global:batchSize = 100000;
Function Add-FileRow() {
$newRow = $dt.NewRow();
$null = $dt.Rows.Add($newRow);
$newRow["Product_ID"] = $global:xmlReader.GetAttribute("Product_ID");
$newRow["path"] = $global:xmlReader.GetAttribute("path");
$newRow["Updated"] = $global:xmlReader.GetAttribute("Updated");
$newRow["Quality"] = $global:xmlReader.GetAttribute("Quality");
$newRow["Supplier_id"] = $global:xmlReader.GetAttribute("Supplier_id");
$newRow["Prod_ID"] = $global:xmlReader.GetAttribute("Prod_ID");
$newRow["Catid"] = $global:xmlReader.GetAttribute("Catid");
$newRow["On_Market"] = $global:xmlReader.GetAttribute("On_Market");
$newRow["Model_Name"] = $global:xmlReader.GetAttribute("Model_Name");
$newRow["Product_View"] = $global:xmlReader.GetAttribute("Product_View");
$newRow["HighPic"] = $global:xmlReader.GetAttribute("HighPic");
$newRow["HighPicSize"] = $global:xmlReader.GetAttribute("HighPicSize");
$newRow["HighPicWidth"] = $global:xmlReader.GetAttribute("HighPicWidth");
$newRow["HighPicHeight"] = $global:xmlReader.GetAttribute("HighPicHeight");
$newRow["Date_Added"] = $global:xmlReader.GetAttribute("Date_Added");
}
# init data table schema
$da = New-Object System.Data.SqlClient.SqlDataAdapter("SELECT * FROM
files_index WHERE 0 = 1", $global:connectionString);
$null = $da.Fill($global:dt);
$bcp = New-Object System.Data.SqlClient.SqlBulkCopy($global:connectionString);
$bcp.DestinationTableName = "dbo.files_index";
$recordCount = 0;
while($xmlReader.Read() -eq $true)
{
if(($xmlReader.NodeType -eq [System.Xml.XmlNodeType]::Element) -and
($xmlReader.Name -eq "file"))
{
Add-FileRow -xmlReader $xmlReader;
$recordCount += 1;
if(($recordCount % $global:batchSize) -eq 0)
{
$bcp.WriteToServer($dt);
$dt.Rows.Clear();
Write-Host "$recordCount file elements processed so far";
}
}
}
if($dt.Rows.Count -gt 0)
{
$bcp.WriteToServer($dt);
}
$bcp.Close();
$xmlReader.Close();
Write-Host "$recordCount file elements imported ";
catch
{
throw;
}
這足夠接近,可以標記為以下內容的重復...
在SQL Server中導入和解析大型XML文件(“正常”方法相當慢時)
接受的答案:
好。 我在XML數據列上創建了XML索引。 (現在只是一個主要的)。 現在,花費約4:30分鍾的查詢現在花費約9秒! 似乎一個存儲有適當XML索引的XML並使用xml.nodes()函數解析數據的表是可行的解決方案。
提高將大型xml文件(〜300 MB)轉換為SQL Server中的關系表的性能
接受的答案:
我對此進行了另一番研究,可以重現您的問題。 嘗試將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時,一個查詢執行得更快有什么意義? 最后,最快,最具擴展性的方法(IMHO)是SSIS。 與我的裝備中的上述方法相同的文件,此版本運行約10秒鍾。 SSIS XML導入方法創建一個包,添加一個Data Flow任務,添加一個XML Source,然后添加每個表。 我創建了一個結構與您相同的300MB文件,並在大約10秒鍾內加載了該文件,例如
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.