массовая вставка в SQL Server, операторы вставки против одного оператора вставки XML? - PullRequest
4 голосов
/ 16 мая 2010

Прикладному уровню (ColdFusion) необходимо вставить несколько строк в SQL Server 2005.

Я думал об использовании цикла на уровне приложения для создания нескольких операторов ввода и отправки в SQL Server через JDBC в одном соединении.

Однако мой коллега предлагает создать XML и вместо этого вставить XML.

Какой метод лучше?

Ответы [ 3 ]

4 голосов
/ 16 мая 2010

Для вставки миллионов строк я использовал BULK INSERT, записывая данные в файл CSV, к которому имеет доступ экземпляр SQL Server. Это превосходит любой тип вставки через JDBC, но за счет снижения гибкости. Для меньшего числа строк можно использовать JDBC Statement.addBatch() и Statement.executeBatch(), чтобы избежать накладных расходов на отправку множества небольших команд.

В зависимости от ваших требований вам, возможно, придется объединить все это в одну транзакцию, или вы сможете разделить ее на несколько транзакций, если не требуются полные гарантии ACID для всего набора данных.

Вот статья, в которой обсуждается массовая вставка XML . У меня нет данных, на которых можно было бы сделать какие-либо выводы, но я бы предположил, что BULK INSERT необработанные данные строк будут быстрее, поскольку преобразование OPENXML не требуется. Конечно, если ваши данные уже находятся в XML, то это имеет смысл, но если нет, то использование табличных данных, вероятно, является самым простым и, возможно, наиболее производительным.

2 голосов
/ 18 мая 2010

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

По сути, вы отправляете данные XML в виде одного аргумента, а затем внутри SP вы запускаете инструкцию INSERT INTO SELECT, выбирая из XML несколько таблиц или групп таблиц.

<code>DECLARE @FOO xml;

SET @FOO = '<things><thing><id>1</id></thing><thing><id>2</id></thing><thing><id>3</id></thing><thing><id>4</id></thing></things>';

SELECT 
    ParamValues.id.value('.', 'int') AS thing_id
FROM 
    @FOO.nodes('/things/thing/id') AS ParamValues(id)

Это создаст таблицу с одним столбцом "thing_id". Теперь все, что вам нужно сделать, это что-то вроде

<code>INSERT INTO someTable (someID)
SELECT 
    ParamValues.id.value('.', 'int') AS thing_id
FROM 
    @FOO.nodes('/things/thing/id') AS ParamValues(id)

и у вас есть один INSERT для обработки любого количества строк XML.

1 голос
/ 16 мая 2010

Одна вставка за раз будет излишне медленной из-за всей этой задержки в сети.

Лучше всего было бы отправить несколько транзакций в виде одного пакета за один прием в обе стороны сети и зафиксировать их как одну единицу работы.

Если у вас очень большое количество записей, возможно, вы захотите рассмотреть гибридный подход: переберите несколько пакетов и отправьте их для фиксации как единицы работы. Это сработает даже для крупных транзакций, и вы не заставите свою базу данных вести большой журнал отката перед фиксацией всей транзакции.

Я не фанат, если ваше решение XML подразумевает вставку необработанного потока XML в виде CLOB. Как вы будете запрашивать его, когда он будет в базе данных? Вы теряете все, что дает вам SQL: возможность запроса. Все, что вы можете сделать, это XPath для определенных значений, если вы храните необработанный XML. А обновления означают замену всего CLOB.

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