Здравствуйте!
Вопрос в следующем.
Есть база в MS SQL 2000. А в ней 2 таблицы, связанные по первичному ключу.
Путь это будут
Table1 и Table2.
1 -> M
ID T1_ID
Таблицы большие. Допустим, Table1 содержит 50тыс. записей.
Table1.ID при вставке назначается инкрементом по Identity.
Каждая строка с Table1.ID содержит N(~200) строк для Table2.T1_ID = Table1.ID
Есть возможность выборки частями из Table1.
Вопрос заключается в том, как мне более шустро скопировать содержимое Table1 и Table2, скажем, в другую связку таблиц (в эти же таблицы, в те же таблицы на другой БД)?
Сейчас я перегоняю через ADO.NET путем
1. вставки строки в Table1,
2. выяснения scope_identity(),
3. заполнения DataSet для Table2,
4. выполения Update.
20 тыс. строк Table1 вставляются за 5,5 мин. Если со вставкой Table2, то за 1,5 часа.
Это медленно. Интересны ваши соображения на этот счет, коллеги, которым приходилось решать подобные задачи.
Если предложите вариант с хранимыми процедурами, временными таблицами — тоже интересно было бы.
Здравствуйте, VZakharin, Вы писали:
VZ>Здравствуйте! VZ>Вопрос в следующем. VZ>Есть база в MS SQL 2000. А в ней 2 таблицы, связанные по первичному ключу. VZ>Путь это будут
VZ>Table1 и Table2. VZ>1 -> M VZ> ID T1_ID
VZ>Таблицы большие. Допустим, Table1 содержит 50тыс. записей. VZ>Table1.ID при вставке назначается инкрементом по Identity. VZ>Каждая строка с Table1.ID содержит N(~200) строк для Table2.T1_ID = Table1.ID VZ>Есть возможность выборки частями из Table1.
VZ>Вопрос заключается в том, как мне более шустро скопировать содержимое Table1 и Table2, скажем, в другую связку таблиц (в эти же таблицы, в те же таблицы на другой БД)? VZ>Сейчас я перегоняю через ADO.NET путем VZ>1. вставки строки в Table1, VZ>2. выяснения scope_identity(), VZ>3. заполнения DataSet для Table2, VZ>4. выполения Update.
VZ>20 тыс. строк Table1 вставляются за 5,5 мин. Если со вставкой Table2, то за 1,5 часа. VZ>Это медленно. Интересны ваши соображения на этот счет, коллеги, которым приходилось решать подобные задачи. VZ>Если предложите вариант с хранимыми процедурами, временными таблицами — тоже интересно было бы.
VZ>Заранее спасибо.
А другая БД это не MS sql 2000? Если это она то наверное там есть механизм называемый database link в oracle
..и пусть умоются кровью те кто сомневается в нашем миролюбии.....
Здравствуйте, VZakharin, Вы писали:
VZ>Здравствуйте! VZ>Вопрос в следующем.
VZ>Это медленно. Интересны ваши соображения на этот счет, коллеги, которым приходилось решать подобные задачи. VZ>Если предложите вариант с хранимыми процедурами, временными таблицами — тоже интересно было бы.
1. Для каждой записи из table1 делаем xml примерно следующего вида:
<Root>
<table1_item name ="name1".../>
<table2_item name = "child_name" ..../>
<table2_item name = "child_name" ..../>
...
<Root>
2. Делаем примерно такую процедуру:
create PROCEDURE [dbo].[save_data] @XML ntext
AS
declare @idoc int
declare @err int
exec @err = sp_xml_preparedocument @idoc OUTPUT, @XML
select @err = @@error + coalesce(@err, 4711)
if @err <> 0 return @err
insert into [Table1] ([name], ....)
select name, .... from
OPENXML(@idoc, '/root/table1_item', 1) WITH (name varchar(50), ...)
set @id = scope_identity ()
insert into [table2] (table2_id,name, ...)
select @id, name, ... from
OPENXML(@idoc, '/root/table2_item', 1) WITH (name varchar(50),...)
EXEC sp_xml_removedocument @idoc
3. Вызываем из клиента данную процедуру, давая ей правильные xml. Время должно быть сопоставимо со вставкой данных только в table1 (в зависимости от размера данных в table2), так как не будет накладных расходов на получение identity и вставку данных в table2 по одной записи.
ЗЫ. можно попробовать все данные в один xml упаковать, но как это сделать, не знаю )
VZ>Заранее спасибо.
дв не за что.
Шурыгин Сергей
"Не следует преумножать сущности сверх необходимости" (с) Оккам
Re[2]: Быстрая вставка двух больших связанных таблиц
Здравствуйте, VZakharin, Вы писали:
VZ>Это медленно. Интересны ваши соображения на этот счет,
Это действительно медленно. Могу дать ориентир по времени — это копирование связки с перепробивкой ключей на Oracle на моей рабочей станции (локальный сервер), таблицы шириной байт по пятьдесят:
SQL> insert all
2 when rec_no = 1 then
3 into master2 ( id, data )
4 values ( m_seq.nextval, master_data )
5 when 1 = 1 then
6 into detail2 ( id, master_id, data )
7 values ( d_seq.nextval, m_seq.currval, detail_data )
8 select m1.data master_data, d1.data detail_data, row_number() over (partition by m1.id order by d1.id) rec_no
9 from master1 m1, detail1 d1
10 where m1.id = d1.master_id
11 ;
1049999 rows inserted
Executed in 61,688 seconds