Ускорение импорта XML на сервер SQL - PullRequest
0 голосов
/ 07 марта 2020

Здравствуйте, у меня есть работающий скрипт Powershell для импорта большого XML файла, с которым я регулярно работаю, на мой SQL сервер.

Файл слишком велик для прямого импорта (4,5 ГБ), поэтому Powershell Пользователь сценария @Tomalak мне очень помог, в настоящее время работает нормально, но все еще занимает 2 с лишним часа. Я пытаюсь найти более быстрый вариант.

Ссылка на предыдущий пост о создании сценария

Я пытаюсь ускорить процесс и недавно думал о разделении XML на файлы меньшего размера и циклическое использование с помощью Bulk Insert SQL, возможно, Разделение файла и использование Powershell, но параллельное его выполнение.

Будет ли Bulk вставка работать быстрее, чем powershell при вставке данных? Кроме того, я не думаю, что вставки, которые занимают больше времени за циклом и извлечением данных из файла XML, сами себя.

Может кто-нибудь указать мне в другом направлении или предложить способ, который бы справиться с этой задачей быстрее?

Открыть для всех вариантов.

Спасибо за потраченное время.

Ответы [ 2 ]

1 голос
/ 07 марта 2020

Вы могли бы получить выгоду от выполнения некоторой оптимизации на XML перед выполнением импорта. XML файлы по своей природе раздуты. Уменьшение длины имен тегов может оказать драматическое c влияние на размер файла (и, следовательно, на производительность анализа). Например, изменив «ProductID» на «P». Это даже не должен быть каждый тег в файле, только более общие. Мне удалось уменьшить размер файла XML от 50 до 80%. Конечно, вам придется изменить свой импорт, чтобы читать в новых именах полей.

Вы можете поэкспериментировать, потянув часть вашего XML в редактор и глобально искать / заменять имена тегов, чтобы увидеть, как это влияет размер файла.

0 голосов
/ 07 марта 2020

Хорошо, поэтому, используя предложение @Matthius R. jessen, я разбил свой основной файл на куски по 500000

Разделил файл с помощью этого программного обеспечения Редактор Firstobject XMl (бесплатно) можно вызвать из командная строка и была в состоянии загрузить очень большой файл xml, где другие биты программного обеспечения боролись.

Затем я использовал это, чтобы извлечь данные из файла разделения.

USE [OPENXMLTesting]
GO

DROP TABLE [dbo].[XMLwithOpenXML]
GO

SET ANSI_NULLS ON 
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[XMLwithOpenXML](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [XMLData] [xml] NULL,
    [LoadedDateTime] [datetime] NULL,
PRIMARY KEY CLUSTERED 
(
    [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] TEXTIMAGE_ON [PRIMARY]

GO

USE OPENXMLTesting
GO

INSERT INTO XMLwithOpenXML(XMLData, LoadedDateTime)
SELECT CONVERT(XML, BulkColumn) AS BulkColumn, GETDATE() 
FROM OPENROWSET(BULK 'C:\Scripts\ImportTest\piece1.xml', SINGLE_BLOB) AS x;

SELECT * FROM XMLwithOpenXML

Общее время 34 секунд для вставки данных в SQL

, а затем запрашивает результаты для основных данных, которые я хотел получить от элемента, используя

USE OPENXMLTesting
GO

DECLARE @XML AS XML, @hDoc AS INT, @SQL NVARCHAR (MAX)

SELECT @XML = XMLData FROM XMLwithOpenXML

EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML

SELECT Product_ID, path, Updated, Quality, Supplier_id, Prod_ID, Catid, On_Market, 
Model_Name, Product_View, HighPic, HighPicSize, HighPicWidth, HighPicHeight, 
Date_Added
FROM OPENXML(@hDoc, 'root/file')
WITH 
(
`Product_ID [int] '@Product_ID',
path [varchar](100) '@path',
Updated [varchar](50) '@Updated',
Quality [varchar](50) '@Quality',
Supplier_id [int] '@Supplier_id',
Prod_ID [varchar] '@Prod_ID',
Catid [int] '@Catid',
On_Market [int] '@On_Market',
Model_Name [varchar](250) '@Model_Name',
Product_View [int] '@Product_View',
HighPic [varchar] '@HighPic',
HighPicSize [int] '@HighPicSize',
HighPicWidth [int] '@HighPicWidth',
HighPicHeight [int] '@HighPicHeight',
Date_Added [varchar](150) '@Date_Added'
)


EXEC sp_xml_removedocument @hDoc
GO

Общее время для этот шаг 57 секунд для извлечения дочернего элемента root и его атрибутов

Затем, когда мне нужно было вернуть дочерний элемент, а также ссылающийся Prod_ID из родительского элемента, так Позже я могу выполнить объединение с данными.

Я пробежал

USE OPENXMLTesting
GO

DECLARE @XML AS XML, @hDoc AS INT, @SQL NVARCHAR (MAX)

SELECT @XML = XMLData FROM XMLwithOpenXML

EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML

SELECT Prod_ID, M_Prod_ID
FROM OPENXML(@hDoc, 'root/file/M_Prod_ID',2)
WITH 
(
Prod_ID [varchar] (50) '../@Prod_ID',
M_Prod_ID [varchar] (50) '../M_Prod_ID'
)

EXEC sp_xml_removedocument @hDoc
GO

Всего 32 секунд .

Так что общее время, чтобы вытащить и запросить 500 000 строк элемента, который я хотел, и дитя т шляпа заняла 2 минуты 3 секунды . не фактическая вставка, а выбор, так что может быть немного больше, чтобы получить данные в БД, но не намного.

Затем я попробовал то же самое, используя мой старый скрипт Powershell, и это заняло 6 минут 39 секунд .

если работать с целым файлом, теперь это займет примерно 32 минуты по сравнению с 2,5 часами, поэтому значительное улучшение. Все, что мне нужно сделать сейчас, это написать скрипт для l oop через разделенные файлы и импортировать один за другим.

Спасибо за все предложения. Я доволен результатами. Возможно, я смогу еще немного ускорить его, очистив XML еще раньше, но сейчас я очень доволен тем, что теперь будет гораздо более коротким процессом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...