Быстрая вставка двух больших связанных таблиц
От: VZakharin  
Дата: 24.10.06 09:32
Оценка:
Здравствуйте!
Вопрос в следующем.
Есть база в 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 часа.
Это медленно. Интересны ваши соображения на этот счет, коллеги, которым приходилось решать подобные задачи.
Если предложите вариант с хранимыми процедурами, временными таблицами — тоже интересно было бы.

Заранее спасибо.
...и чего нет, того нельзя сосчитать.
Re: Быстрая вставка двух больших связанных таблиц
От: zorgio  
Дата: 24.10.06 09:48
Оценка:
Здравствуйте, 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
..и пусть умоются кровью те кто сомневается в нашем миролюбии.....
Re: Быстрая вставка двух больших связанных таблиц
От: Sshur Россия http://shurygin-sergey.livejournal.com
Дата: 24.10.06 10:07
Оценка:
Здравствуйте, 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]: Быстрая вставка двух больших связанных таблиц
От: Sshur Россия http://shurygin-sergey.livejournal.com
Дата: 24.10.06 10:11
Оценка:
Здравствуйте, Sshur, Вы писали:

Я пропустил в посте слова "в другую БД". Предложенный мной вариант будет работать только в MSSQL, но в таком случае есть более простые способы
Шурыгин Сергей

"Не следует преумножать сущности сверх необходимости" (с) Оккам
Re: Быстрая вставка двух больших связанных таблиц
От: Softwarer http://softwarer.ru
Дата: 24.10.06 10:44
Оценка:
Здравствуйте, 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
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.