powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Сохранение 10000 записей в одной процедуре
30 сообщений из 30, показаны все 2 страниц
Сохранение 10000 записей в одной процедуре
    #39962008
lana92
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем привет, подскажите пожалуйста как сохранить 10000 записей в одной процедуре, как лучше реализовать
через insert в цикле php долго
пытаюсь сохранить данные экг
...
Рейтинг: 0 / 0
Сохранение 10000 записей в одной процедуре
    #39962013
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
lana92
Всем привет, подскажите пожалуйста как сохранить 10000 записей в одной процедуре, как лучше реализовать
через insert в цикле php долго
пытаюсь сохранить данные экг
Для сиквела лучше получать данные пакетом (передавая в процедуру параметр типа "таблица", либо используя балк-операции)
Но как это можно реализовать, нужно спрашивать в разделе php
...
Рейтинг: 0 / 0
Сохранение 10000 записей в одной процедуре
    #39962014
Glebanski
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
lana92,

В php ни в зуб ногой. Но чисто из теоретических соображений поинтересуюсь : на каждый insert новый connect делаете?

PS : вообще отличный кейс для моего "пыточного аппарата" для студентов :)
...
Рейтинг: 0 / 0
Сохранение 10000 записей в одной процедуре
    #39962019
Фотография a_voronin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
lana92
Всем привет, подскажите пожалуйста как сохранить 10000 записей в одной процедуре, как лучше реализовать
через insert в цикле php долго
пытаюсь сохранить данные экг


В php есть библиотека с BulkInsert ? В C# вы набиваете данные в DataSet и делаете ему BulkInsert. Через класс SqlBulkCopy . Посмотрите, есть ли эквивалент под PHP.
...
Рейтинг: 0 / 0
Сохранение 10000 записей в одной процедуре
    #39962023
lana92
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Glebanski,

ну сперва сделал процедуру для insert и каждый раз ее вызывал, и так получалось каждый раз коннектиться при прохождении по циклу, а это не очень.
Потом изменил: собирал в цикле список values и уже разом отправлял insert, но есть ограничение на 1000 записей, можно конечно разделить массив на 10 insert, но мне кажется это тоже совсем не лучшее решение
...
Рейтинг: 0 / 0
Сохранение 10000 записей в одной процедуре
    #39962036
Фотография crutchmaster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
lana92,

Код где?
Должен быть какой-то bulk insert ковыряй свою библиотеку mssql для пыха.
https://www.php.net/manual/ru/function.sqlsrv-prepare.php
...
Рейтинг: 0 / 0
Сохранение 10000 записей в одной процедуре
    #39962493
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Отдайте все эти 10000 записей в параметр хранимой процедуры в виде xml или json (второе - если сервер 2016+), внутри средствами sql разберите, и вставляйте, сколько душе угодно.
...
Рейтинг: 0 / 0
Сохранение 10000 записей в одной процедуре
    #39962656
Фотография SQL2008
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
uaggster
Отдайте все эти 10000 записей в параметр хранимой процедуры в виде xml или json (второе - если сервер 2016+), внутри средствами sql разберите, и вставляйте, сколько душе угодно.

Злодей!
...
Рейтинг: 0 / 0
Сохранение 10000 записей в одной процедуре
    #39962658
Фотография a_voronin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
uaggster
Отдайте все эти 10000 записей в параметр хранимой процедуры в виде xml или json (второе - если сервер 2016+), внутри средствами sql разберите, и вставляйте, сколько душе угодно.



Партянка из INSERT будет быстрее, чем парзить строки, xml, json.
...
Рейтинг: 0 / 0
Сохранение 10000 записей в одной процедуре
    #39962735
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Притом в начале вставок явно открыть транзакцию, в конце закрыть. Вообще муть какая-то, в этом случае загрузку лучше сделать через файл и утилиту bcp.
...
Рейтинг: 0 / 0
Сохранение 10000 записей в одной процедуре
    #39962740
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a_voronin
Партянка из INSERT будет быстрее, чем парзить строки, xml, json.
А как же время на компиляцию портянки из 10000 insert'ов?
...
Рейтинг: 0 / 0
Сохранение 10000 записей в одной процедуре
    #39962778
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
a_voronin
uaggster
Отдайте все эти 10000 записей в параметр хранимой процедуры в виде xml или json (второе - если сервер 2016+), внутри средствами sql разберите, и вставляйте, сколько душе угодно.



Партянка из INSERT будет быстрее, чем парзить строки, xml, json.

Да щас, конечно.
Во первых, чтобы это хоть как то сравнилось по скорости - это нужно обрамить внешней транзакцией, а во вторых оформить сам запрос на вставку как параметризованный.
Кроме того, всё это нужно проделать в одном коннекте.
И даже в этом случае - 10 тыс. вызовов, притом синхронных, с клиента - это та еще песня.

Разница будет раз в 100, в пользу парсинга json или openxml.
...
Рейтинг: 0 / 0
Сохранение 10000 записей в одной процедуре
    #39962876
Фотография a_voronin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
uaggster
a_voronin
пропущено...



Партянка из INSERT будет быстрее, чем парзить строки, xml, json.

Да щас, конечно.
Во первых, чтобы это хоть как то сравнилось по скорости - это нужно обрамить внешней транзакцией, а во вторых оформить сам запрос на вставку как параметризованный.
Кроме того, всё это нужно проделать в одном коннекте.
И даже в этом случае - 10 тыс. вызовов, притом синхронных, с клиента - это та еще песня.

Разница будет раз в 100, в пользу парсинга json или openxml.


А вы тест проведите. Я такой делал.

Имеется ввиду парзить XML - JSON, против отправки десятка команд по 1000 INSERT. Речь не идет о выполнении INSERT по одному. BULK INSERT не рассматриваем, ибо он еще быстрее.
...
Рейтинг: 0 / 0
Сохранение 10000 записей в одной процедуре
    #39962908
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a_voronin
А вы тест проведите. Я такой делал.
Покажите как.

Тест
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
use tempdb;
set ansi_nulls, quoted_identifier, xact_abort on;
go

create table dbo.s (id int, a int, b nvarchar(100), c nchar(2000));
go

insert into dbo.s
 (id, a, b, c)
 select top (100000)
  row_number() over (order by 1/0), 1, cast(newid() as nvarchar(100)), replicate(N'a', 2000)
 from
  master.dbo.spt_values a cross join
  master.dbo.spt_values b;
go

select top (0) * into dbo.t1 from dbo.s;
select top (0) * into dbo.t2 from dbo.s;
go

declare @q nvarchar(max), @dt datetime2, @x xml;
declare @result table (descr nvarchar(30), rows_affected bigint, [elapsed_time (ms)] int);

select
 @q = N'begin tran; ' + t.x.value('.', 'nvarchar(max)') + N' commit;'
from
 (
  select
   N'insert into dbo.t1 (id, a, b, c) values (' + cast(id as nvarchar(10)) + N', ' + cast(a as nvarchar(10)) + N', ''' + b + ''', ''' + c + ''');' 
  from
   dbo.s
  for xml path(''), type
 ) t(x);

set @dt = sysdatetime();
exec(@q);
insert into @result
 (descr, rows_affected, [elapsed_time (ms)])
 select N'footcloth of inserts', count(*), datediff(ms, @dt, sysdatetime()) from dbo.t1;

select
 @x = t.x
from
 (
  select
   id as [@id], a as [@a], b as [@b], c as [@c]
  from
   dbo.s
  for xml path('item'), type
 ) t(x);

set @dt = sysdatetime();
insert into dbo.t2
 (id, a, b, c)
 select
  t.n.value('@id', 'int'),
  t.n.value('@a', 'int'),
  t.n.value('@b', 'nvarchar(100)'),
  t.n.value('@c', 'nchar(2000)')
 from
  @x.nodes('item') t(n);
insert into @result
 (descr, rows_affected, [elapsed_time (ms)])
 select N'xml', count(*), datediff(ms, @dt, sysdatetime()) from dbo.t2;

select * from @result order by [elapsed_time (ms)];
go

drop table dbo.s, dbo.t1, dbo.t2;
go


descrrows_affectedelapsed_time (ms)xml1000002924footcloth of inserts10000017503
...
Рейтинг: 0 / 0
Сохранение 10000 записей в одной процедуре
    #39962913
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я как-то проводил клиент-серверные тесты, наиболее выгодным оказалась вставка по 800-600 INSERT в пачке и это мало зависело от ширины таблицы по сравнению с XML. Тем не менее, XML оказался форматом с боле простой реализацией и иногда показывал сравнимые результаты.
...
Рейтинг: 0 / 0
Сохранение 10000 записей в одной процедуре
    #39962955
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a_voronin, Владислав Колосов, и какие же были методики тестирования?

Добавим "пачки"
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
use tempdb;
set ansi_nulls, quoted_identifier, xact_abort on;
set nocount on;
go

create table dbo.s (id int, a int, b nvarchar(100), c nchar(2000));
go

insert into dbo.s
 (id, a, b, c)
 select top (100000)
  row_number() over (order by 1/0), 1, cast(newid() as nvarchar(100)), replicate(N'a', 2000)
 from
  master.dbo.spt_values a cross join
  master.dbo.spt_values b;
go

select top (0) * into dbo.t1 from dbo.s;
select top (0) * into dbo.t2 from dbo.s;
select top (0) * into dbo.t3 from dbo.s;
go

declare @q nvarchar(max), @dt datetime2, @x xml;
declare @result table (descr nvarchar(30), rows_affected bigint, [elapsed_time (ms)] int);

select
 @q = N'begin tran; ' + t.x.value('.', 'nvarchar(max)') + N' commit;'
from
 (
  select
   N'insert into dbo.t1 (id, a, b, c) values (' + cast(id as nvarchar(10)) + N', ' + cast(a as nvarchar(10)) + N', ''' + b + ''', ''' + c + ''');' 
  from
   dbo.s
  for xml path(''), type
 ) t(x);

declare @t table (q nvarchar(max));

insert into @t
 (q)
select
 b.q
from
 (select top (100) row_number() over (order by 1/0) - 1 from master.dbo.spt_values) a(n) cross apply
 (
  select top (1000)
   N'insert into dbo.t3 (id, a, b, c) values (' + cast(id as nvarchar(10)) + N', ' + cast(a as nvarchar(10)) + N', ''' + b + ''', ''' + c + ''');' 
  from
   dbo.s
  where
   id > a.n * 1000
  for xml path(''), type
 ) t(x) cross apply
 (select N'begin tran; ' + t.x.value('.', 'nvarchar(max)') + N' commit;') b(q)
where
 b.q is not null;

set @dt = sysdatetime();
exec(@q);
insert into @result
 (descr, rows_affected, [elapsed_time (ms)])
 select N'footcloth of inserts', count(*), datediff(ms, @dt, sysdatetime()) from dbo.t1;

select
 @x = t.x
from
 (
  select
   id as [@id], a as [@a], b as [@b], c as [@c]
  from
   dbo.s
  for xml path('item'), type
 ) t(x);

set @dt = sysdatetime();
insert into dbo.t2
 (id, a, b, c)
 select
  t.n.value('@id', 'int'),
  t.n.value('@a', 'int'),
  t.n.value('@b', 'nvarchar(100)'),
  t.n.value('@c', 'nchar(2000)')
 from
  @x.nodes('item') t(n);
insert into @result
 (descr, rows_affected, [elapsed_time (ms)])
 select N'xml', count(*), datediff(ms, @dt, sysdatetime()) from dbo.t2;

declare t cursor local fast_forward for
 select q from @t;

open t;
set @dt = sysdatetime();

while 1 = 1
 begin
  fetch next from t into @q;
  if @@fetch_status <> 0
   break;

  exec(@q);
 end;
close t;
deallocate t;
insert into @result
 (descr, rows_affected, [elapsed_time (ms)])
 select N'batches of inserts', count(*), datediff(ms, @dt, sysdatetime()) from dbo.t3;

select * from @result order by [elapsed_time (ms)];
go

drop table dbo.s, dbo.t1, dbo.t2, dbo.t3;
go


descrrows_affectedelapsed_time (ms)xml1000003033batches of inserts10000011310footcloth of inserts10000015806
...
Рейтинг: 0 / 0
Сохранение 10000 записей в одной процедуре
    #39962977
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invm,

приложение читало данные из файла, формировало строки INSERT запросов в пачки по заданному количеству строк и выполняло полученный код на сервере до исчерпания строк в источнике. Либо локально формировал XML и отправлял его на сервер во временную процедуру, которую же создавало приложение. Использовал ODBC протокол. Но это было давно, во времена Windows XP.
...
Рейтинг: 0 / 0
Сохранение 10000 записей в одной процедуре
    #39962984
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владислав Колосов,

Во времена XP все было несколько по-другому...

Более корректный тест
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
use tempdb;
set ansi_nulls, quoted_identifier, xact_abort on;
set nocount on;
go

create table dbo.s (id int, a int, b nvarchar(100), c nchar(2000));
go

insert into dbo.s
 (id, a, b, c)
 select top (100000)
  row_number() over (order by 1/0), 1, cast(newid() as nvarchar(100)), replicate(N'a', 2000)
 from
  master.dbo.spt_values a cross join
  master.dbo.spt_values b;
go

select top (0) * into dbo.t1 from dbo.s;
select top (0) * into dbo.t2 from dbo.s;
select top (0) * into dbo.t3 from dbo.s;
go

declare @q nvarchar(max), @dt datetime2, @sx nvarchar(max), @x xml;
declare @result table (descr nvarchar(30), rows_affected bigint, [elapsed_time (ms)] int);

select
 @q = N'begin tran; ' + t.x.value('.', 'nvarchar(max)') + N' commit;'
from
 (
  select
   N'insert into dbo.t1 (id, a, b, c) values (' + cast(id as nvarchar(10)) + N', ' + cast(a as nvarchar(10)) + N', ''' + b + ''', ''' + c + ''');' 
  from
   dbo.s
  for xml path(''), type
 ) t(x);

declare @t table (q nvarchar(max));

insert into @t
 (q)
select
 b.q
from
 (select top (100) row_number() over (order by 1/0) - 1 from master.dbo.spt_values) a(n) cross apply
 (
  select top (1000)
   N'insert into dbo.t3 (id, a, b, c) values (' + cast(id as nvarchar(10)) + N', ' + cast(a as nvarchar(10)) + N', ''' + b + ''', ''' + c + ''');' 
  from
   dbo.s
  where
   id > a.n * 1000
  for xml path(''), type
 ) t(x) cross apply
 (select N'begin tran; ' + t.x.value('.', 'nvarchar(max)') + N' commit;') b(q)
where
 b.q is not null;

set @dt = sysdatetime();
exec(@q);
insert into @result
 (descr, rows_affected, [elapsed_time (ms)])
 select N'footcloth of inserts', count(*), datediff(ms, @dt, sysdatetime()) from dbo.t1;

select
 @sx = t.x
from
 (
  select
   id as [@id], a as [@a], b as [@b], c as [@c]
  from
   dbo.s
  for xml path('item')--, type
 ) t(x);

set @dt = sysdatetime();

set @x = @sx;
insert into dbo.t2
 (id, a, b, c)
 select
  t.n.value('@id', 'int'),
  t.n.value('@a', 'int'),
  t.n.value('@b', 'nvarchar(100)'),
  t.n.value('@c', 'nchar(2000)')
 from
  @x.nodes('item') t(n);
insert into @result
 (descr, rows_affected, [elapsed_time (ms)])
 select N'xml', count(*), datediff(ms, @dt, sysdatetime()) from dbo.t2;

declare t cursor local fast_forward for
 select q from @t;

open t;
set @dt = sysdatetime();

while 1 = 1
 begin
  fetch next from t into @q;
  if @@fetch_status <> 0
   break;

  exec(@q);
 end;
close t;
deallocate t;
insert into @result
 (descr, rows_affected, [elapsed_time (ms)])
 select N'batches of inserts', count(*), datediff(ms, @dt, sysdatetime()) from dbo.t3;

select * from @result order by [elapsed_time (ms)];
go

drop table dbo.s, dbo.t1, dbo.t2, dbo.t3;
go


descrrows_affectedelapsed_time (ms)xml1000008080batches of inserts10000010239footcloth of inserts10000016092
...
Рейтинг: 0 / 0
Сохранение 10000 записей в одной процедуре
    #39963031
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
invm, возможно, через openxml - будет еще быстрее.
...
Рейтинг: 0 / 0
Сохранение 10000 записей в одной процедуре
    #39963052
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
uaggster, возможно. Особенно, если столбцов будет много.
...
Рейтинг: 0 / 0
Сохранение 10000 записей в одной процедуре
    #39963153
Фотография Ennor Tiegael
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
lana92,

Ваш случай , практ. один в один. Тоже с пхп, опять-таки.

Ну и вроде уже обсуждали производительность альтернативных вариантов такой вставки, table type обгоняет всех, кроме bulk insert.
...
Рейтинг: 0 / 0
Сохранение 10000 записей в одной процедуре
    #39963187
Фотография a_voronin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invm
a_voronin, Владислав Колосов, и какие же были методики тестирования?

Добавим "пачки"
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
use tempdb;
set ansi_nulls, quoted_identifier, xact_abort on;
set nocount on;
go

create table dbo.s (id int, a int, b nvarchar(100), c nchar(2000));
go

insert into dbo.s
 (id, a, b, c)
 select top (100000)
  row_number() over (order by 1/0), 1, cast(newid() as nvarchar(100)), replicate(N'a', 2000)
 from
  master.dbo.spt_values a cross join
  master.dbo.spt_values b;
go

select top (0) * into dbo.t1 from dbo.s;
select top (0) * into dbo.t2 from dbo.s;
select top (0) * into dbo.t3 from dbo.s;
go

declare @q nvarchar(max), @dt datetime2, @x xml;
declare @result table (descr nvarchar(30), rows_affected bigint, [elapsed_time (ms)] int);

select
 @q = N'begin tran; ' + t.x.value('.', 'nvarchar(max)') + N' commit;'
from
 (
  select
   N'insert into dbo.t1 (id, a, b, c) values (' + cast(id as nvarchar(10)) + N', ' + cast(a as nvarchar(10)) + N', ''' + b + ''', ''' + c + ''');' 
  from
   dbo.s
  for xml path(''), type
 ) t(x);

declare @t table (q nvarchar(max));

insert into @t
 (q)
select
 b.q
from
 (select top (100) row_number() over (order by 1/0) - 1 from master.dbo.spt_values) a(n) cross apply
 (
  select top (1000)
   N'insert into dbo.t3 (id, a, b, c) values (' + cast(id as nvarchar(10)) + N', ' + cast(a as nvarchar(10)) + N', ''' + b + ''', ''' + c + ''');' 
  from
   dbo.s
  where
   id > a.n * 1000
  for xml path(''), type
 ) t(x) cross apply
 (select N'begin tran; ' + t.x.value('.', 'nvarchar(max)') + N' commit;') b(q)
where
 b.q is not null;

set @dt = sysdatetime();
exec(@q);
insert into @result
 (descr, rows_affected, [elapsed_time (ms)])
 select N'footcloth of inserts', count(*), datediff(ms, @dt, sysdatetime()) from dbo.t1;

select
 @x = t.x
from
 (
  select
   id as [@id], a as [@a], b as [@b], c as [@c]
  from
   dbo.s
  for xml path('item'), type
 ) t(x);

set @dt = sysdatetime();
insert into dbo.t2
 (id, a, b, c)
 select
  t.n.value('@id', 'int'),
  t.n.value('@a', 'int'),
  t.n.value('@b', 'nvarchar(100)'),
  t.n.value('@c', 'nchar(2000)')
 from
  @x.nodes('item') t(n);
insert into @result
 (descr, rows_affected, [elapsed_time (ms)])
 select N'xml', count(*), datediff(ms, @dt, sysdatetime()) from dbo.t2;

declare t cursor local fast_forward for
 select q from @t;

open t;
set @dt = sysdatetime();

while 1 = 1
 begin
  fetch next from t into @q;
  if @@fetch_status <> 0
   break;

  exec(@q);
 end;
close t;
deallocate t;
insert into @result
 (descr, rows_affected, [elapsed_time (ms)])
 select N'batches of inserts', count(*), datediff(ms, @dt, sysdatetime()) from dbo.t3;

select * from @result order by [elapsed_time (ms)];
go

drop table dbo.s, dbo.t1, dbo.t2, dbo.t3;
go


descrtrows_affectedtelapsed_time (ms)xmlt100000t3033batches of insertst100000t11310footcloth of insertst100000t15806


Я тестировал пуская запрос из клиентской тулзы. Дело было на 2005 и давно.

Ваш тест показывает, что из xml вставляется быстрее, но этот тест не совсем тот случай, который у ТС, у который был у меня. Отсутствует один шаг -- xml приходит в текстовом виде и должен быть сначала распарзен. У вас же на входе подготовленный xml: @x xml;.
...
Рейтинг: 0 / 0
Сохранение 10000 записей в одной процедуре
    #39963204
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a_voronin
Отсутствует один шаг -- xml приходит в текстовом виде и должен быть сначала распарзен.
Смотрите последнюю версию теста.
...
Рейтинг: 0 / 0
Сохранение 10000 записей в одной процедуре
    #39964213
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В общем, из строковых вариантов - самый быстрый json, как и ожидалось.
А вот то, что OPENXML оказался медленнее XQuery - для меня неожиданность.


Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
use tempdb;
set ansi_nulls, quoted_identifier, xact_abort on;
set nocount on;
go

create table dbo.s (id int, a int, b nvarchar(100), c nchar(2000));
go

insert into dbo.s
 (id, a, b, c)
 select top (100000)
  row_number() over (order by 1/0), 1, cast(newid() as nvarchar(100)), replicate(N'a', 2000)
 from
  master.dbo.spt_values a cross join
  master.dbo.spt_values b;
go

select top (0) * into dbo.t1 from dbo.s;
select top (0) * into dbo.t2 from dbo.s;
select top (0) * into dbo.t3 from dbo.s;
select top (0) * into dbo.t4 from dbo.s;
select top (0) * into dbo.t5 from dbo.s;
go

declare @q nvarchar(max), @dt datetime2, @sx nvarchar(max), @x xml, @sj nvarchar(max), @s nvarchar(max);
declare @result table (descr nvarchar(30), rows_affected bigint, [elapsed_time (ms)] int);

select
 @q = N'begin tran; ' + t.x.value('.', 'nvarchar(max)') + N' commit;'
from
 (
  select
   N'insert into dbo.t1 (id, a, b, c) values (' + cast(id as nvarchar(10)) + N', ' + cast(a as nvarchar(10)) + N', ''' + b + ''', ''' + c + ''');' 
  from
   dbo.s
  for xml path(''), type
 ) t(x);

declare @t table (q nvarchar(max));

insert into @t
 (q)
select
 b.q
from
 (select top (100) row_number() over (order by 1/0) - 1 from master.dbo.spt_values) a(n) cross apply
 (
  select top (1000)
   N'insert into dbo.t3 (id, a, b, c) values (' + cast(id as nvarchar(10)) + N', ' + cast(a as nvarchar(10)) + N', ''' + b + ''', ''' + c + ''');' 
  from
   dbo.s
  where
   id > a.n * 1000
  for xml path(''), type
 ) t(x) cross apply
 (select N'begin tran; ' + t.x.value('.', 'nvarchar(max)') + N' commit;') b(q)
where
 b.q is not null;

set @dt = sysdatetime();
exec(@q);
insert into @result
 (descr, rows_affected, [elapsed_time (ms)])
 select N'footcloth of inserts', count(*), datediff(ms, @dt, sysdatetime()) from dbo.t1;

select
 @sx = t.x
from
 (
  select
   id as [@id], a as [@a], b as [@b], c as [@c]
  from
   dbo.s
  for xml path('item')--, type
 ) t(x);

set @dt = sysdatetime();

set @x = @sx;
insert into dbo.t2
 (id, a, b, c)
 select
  t.n.value('@id', 'int'),
  t.n.value('@a', 'int'),
  t.n.value('@b', 'nvarchar(100)'),
  t.n.value('@c', 'nchar(2000)')
 from
  @x.nodes('item') t(n);
insert into @result
 (descr, rows_affected, [elapsed_time (ms)])
 select N'xml', count(*), datediff(ms, @dt, sysdatetime()) from dbo.t2;

set @x = NULL;

set @dt = sysdatetime();

declare @i as int;
set @x = '<root>' + @sx + '</root>';
exec sp_xml_preparedocument @i output, @x;

insert into dbo.t4
 (id, a, b, c)
 select id, a, b, c
 FROM OPENXML (@i, '/root/item', 1) 
				With (id int '@id',
					  a int '@a',
					  b  nvarchar(100) '@b',
					  c  nchar(2000) '@c'
				);
exec sp_xml_removedocument @i

insert into @result
 (descr, rows_affected, [elapsed_time (ms)])
 select N'OPENXML', count(*), datediff(ms, @dt, sysdatetime()) from dbo.t4;

select
 @sj = t.x
from
 (
  select
   id as [id], a as [a], b as [b], c as [c]
  from
   dbo.s
  for json auto
 ) t(x);

set @dt = sysdatetime();

set @s = @sj;
insert into dbo.t5
 (id, a, b, c)
 select  id, a, b, c
 FROM OPENJSON (@s) 
				With (id int '$.id',
					  a int '$.a',
					  b  nvarchar(100) '$.b',
					  c  nchar(2000) '$.c'
				);

insert into @result
 (descr, rows_affected, [elapsed_time (ms)])
 select N'json', count(*), datediff(ms, @dt, sysdatetime()) from dbo.t5;

declare t cursor local fast_forward for
 select q from @t;

open t;
set @dt = sysdatetime();

while 1 = 1
 begin
  fetch next from t into @q;
  if @@fetch_status <> 0
   break;

  exec(@q);
 end;
close t;
deallocate t;
insert into @result
 (descr, rows_affected, [elapsed_time (ms)])
 select N'batches of inserts', count(*), datediff(ms, @dt, sysdatetime()) from dbo.t3; 

select * from @result order by [elapsed_time (ms)];
go

drop table dbo.s, dbo.t1, dbo.t2, dbo.t3, dbo.t4, dbo.t5;
go




descr rows_affected elapsed_time (ms)json 100000 5992xml 100000 8498batches of inserts 100000 14162OPENXML 100000 16069footcloth of inserts 100000 25186
...
Рейтинг: 0 / 0
Сохранение 10000 записей в одной процедуре
    #39964225
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
uaggster
В общем, из строковых вариантов - самый быстрый json, как и ожидалось.
А вот то, что OPENXML оказался медленнее XQuery - для меня неожиданность.

descr rows_affected elapsed_time (ms)json 100000 5992xml 100000 8498batches of inserts 100000 14162OPENXML 100000 16069footcloth of inserts 100000 25186

Ээээ, горе-тестировщики, а сборку JSON-XML выполняет дух святой?
...
Рейтинг: 0 / 0
Сохранение 10000 записей в одной процедуре
    #39964226
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
uaggster
В общем, из строковых вариантов - самый быстрый json, как и ожидалось.
А вот то, что OPENXML оказался медленнее XQuery - для меня неожиданность.

descr rows_affected elapsed_time (ms)json 100000 5992xml 100000 8498batches of inserts 100000 14162OPENXML 100000 16069footcloth of inserts 100000 25186

Ээээ, горе-тестировщики, а сборку JSON-XML выполняет дух святой?
...
Рейтинг: 0 / 0
Сохранение 10000 записей в одной процедуре
    #39964233
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
aleks222
а сборку JSON-XML выполняет дух святой?
Ага. И он же формирует портянку или пакеты инсертов.
...
Рейтинг: 0 / 0
Сохранение 10000 записей в одной процедуре
    #39964234
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
aleks222
uaggster
В общем, из строковых вариантов - самый быстрый json, как и ожидалось.
А вот то, что OPENXML оказался медленнее XQuery - для меня неожиданность.

descr rows_affected elapsed_time (ms)json 100000 5992xml 100000 8498batches of inserts 100000 14162OPENXML 100000 16069footcloth of inserts 100000 25186

Ээээ, горе-тестировщики, а сборку JSON-XML выполняет дух святой?
А сборку строк с insert'ами?
И чем сборка строк с insert'ами отличается от сборки json или xml?
...
Рейтинг: 0 / 0
Сохранение 10000 записей в одной процедуре
    #39964964
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сборка XML дает нестабильный результат, то быстрее, то медленнее. Зависит от многих факторов - и версия парсера, использует DOM, не используется, наличие памяти, загруженность процессора и так далее. Формирование текстовых строк работает предсказуемо. По крайней мере, я получал нестабильные результаты в клиент-серверной связке.
...
Рейтинг: 0 / 0
Сохранение 10000 записей в одной процедуре
    #39965220
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А кто сказал, что хмл надо собирать как хмл, через DOM и всё такое?
хмл - это точно такая же строка, и собирать его нужно также, как строку.
Стабильно и предсказуемо.
:-)))
...
Рейтинг: 0 / 0
30 сообщений из 30, показаны все 2 страниц
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Сохранение 10000 записей в одной процедуре
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]