Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 begin transaction + цикл while  [new]
hanko_nikita
Member

Откуда:
Сообщений: 71
Здравствуйте! Подскажите пожалуйста, возникла такая вот ситуация... Есть вот такой код
use testdb

declare @PriceI float,
  @I_Pos int,
  @Account varchar(50)
set @PriceI = 9910
set @I_Pos = 1
set @Account = 'SPBFUT19FH8'

delete [dbo].[Table_1]
where  [Account] = @Account


BEGIN TRANSACTION

while @I_Pos <= 810
begin

 insert into [dbo].[Table_1]
 values (@Account, 'SPBFUT', 'SRZ3', @PriceI, @PriceI + 10, 1)

 set @PriceI = @PriceI + 10
 set @I_Pos = @I_Pos + 1
end

COMMIT

select * from [dbo].[Table_1]
where [Account] = @Account
order by [Price]
select [Account] from [dbo].[Table_1]
group by [Account]


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


Если убрать транзакцию этот же запрос выполняется порядка 3 сек.
use testdb

declare @PriceI float,
  @I_Pos int,
  @Account varchar(50)
set @PriceI = 9910
set @I_Pos = 1
set @Account = 'SPBFUT19FH8'

delete [dbo].[Table_1]
where  [Account] = @Account

while @I_Pos <= 810
begin

 insert into [dbo].[Table_1]
 values (@Account, 'SPBFUT', 'SRZ3', @PriceI, @PriceI + 10, 1)

 set @PriceI = @PriceI + 10
 set @I_Pos = @I_Pos + 1
end

select * from [dbo].[Table_1]
where [Account] = @Account
order by [Price]
select [Account] from [dbo].[Table_1]
group by [Account]


На другом сервере с 4 ядрами запрос без транзакции выполняется 7 сек, а с транзакцией также меньше секунды. От чего это зависит, в какую сторону копать? Заранее спасибо!
12 дек 13, 15:45    [15283356]     Ответить | Цитировать Сообщить модератору
 Re: begin transaction + цикл while  [new]
Glory
Member

Откуда:
Сообщений: 104751
hanko_nikita
От чего это зависит, в какую сторону копать?

В сторону понимания того, что любая команда изменения данных все равно выполняется в транзакции.
12 дек 13, 15:47    [15283370]     Ответить | Цитировать Сообщить модератору
 Re: begin transaction + цикл while  [new]
Dmitry V. Liseev
Member [заблокирован]

Откуда: Санкт-Петербург
Сообщений: 5489
А план одинаковый?
12 дек 13, 15:48    [15283383]     Ответить | Цитировать Сообщить модератору
 Re: begin transaction + цикл while  [new]
Ramis
Member

Откуда:
Сообщений: 99
может надо попробовать поставить хинты With(nolock)?
12 дек 13, 15:49    [15283385]     Ответить | Цитировать Сообщить модератору
 Re: begin transaction + цикл while  [new]
hanko_nikita
Member

Откуда:
Сообщений: 71
Glory,
Ну так получается что она так и так в транзакции, а почему же тогда такая разница в производительности?
12 дек 13, 15:50    [15283392]     Ответить | Цитировать Сообщить модератору
 Re: begin transaction + цикл while  [new]
Glory
Member

Откуда:
Сообщений: 104751
hanko_nikita
Ну так получается что она так и так в транзакции, а почему же тогда такая разница в производительности?

BEGIN TRANSACTION
while @I_Pos <= 810
begin
 insert into [dbo].[Table_1] values (@Account, 'SPBFUT', 'SRZ3', @PriceI, @PriceI + 10, 1)

 set @PriceI = @PriceI + 10
 set @I_Pos = @I_Pos + 1
end

COMMIT

Это 1 транзакция

while @I_Pos <= 810
begin
 insert into [dbo].[Table_1] values (@Account, 'SPBFUT', 'SRZ3', @PriceI, @PriceI + 10, 1)

 set @PriceI = @PriceI + 10
 set @I_Pos = @I_Pos + 1
end

Это 810 транзакций
12 дек 13, 15:51    [15283403]     Ответить | Цитировать Сообщить модератору
 Re: begin transaction + цикл while  [new]
hanko_nikita
Member

Откуда:
Сообщений: 71
Dmitry V. Liseev,
Да, план одинаковый
12 дек 13, 15:54    [15283416]     Ответить | Цитировать Сообщить модератору
 Re: begin transaction + цикл while  [new]
hanko_nikita
Member

Откуда:
Сообщений: 71
Glory,
То есть это правильно надо заключать цикл в транзакцию? А если в цикле много разных команд на изменения разных таблиц, в этом случае что? А что интересно, есть комп 2 ядра, на которм стоит сервер так на нем без объявления транзакции, выполняется меньше сек., почему так?
12 дек 13, 15:58    [15283441]     Ответить | Цитировать Сообщить модератору
 Re: begin transaction + цикл while  [new]
Glory
Member

Откуда:
Сообщений: 104751
hanko_nikita
То есть это правильно надо заключать цикл в транзакцию?

Да не цикл. А команды.

hanko_nikita
А если в цикле много разных команд на изменения разных таблиц, в этом случае что?

Что, что. Открыть хелп и узнать уже, что такое транзакции и для чего они нужны

hanko_nikita
А что интересно, есть комп 2 ядра, на которм стоит сервер так на нем без объявления транзакции, выполняется меньше сек., почему так?

Наверное потому, что транзакциям наверное не особо важно сколько там ядер на сервере.
12 дек 13, 16:00    [15283461]     Ответить | Цитировать Сообщить модератору
 Re: begin transaction + цикл while  [new]
hanko_nikita
Member

Откуда:
Сообщений: 71
Glory
hanko_nikita
То есть это правильно надо заключать цикл в транзакцию?

Да не цикл. А команды.

hanko_nikita
А если в цикле много разных команд на изменения разных таблиц, в этом случае что?

Что, что. Открыть хелп и узнать уже, что такое транзакции и для чего они нужны

hanko_nikita
А что интересно, есть комп 2 ядра, на которм стоит сервер так на нем без объявления транзакции, выполняется меньше сек., почему так?

Наверное потому, что транзакциям наверное не особо важно сколько там ядер на сервере.


Я имел в виду если в цикле предположим еще 5 разных инсертов в разные таблицы и еще каки-нибудь операции, то правильнее все равно заключить эти все команды в одну транзакцию?
12 дек 13, 16:21    [15283588]     Ответить | Цитировать Сообщить модератору
 Re: begin transaction + цикл while  [new]
Glory
Member

Откуда:
Сообщений: 104751
hanko_nikita
то правильнее все равно заключить эти все команды в одну транзакцию?

Еще раз. Пользовательские тразакции создаются для обеспечения какой-то задачи. А не потому, что "есть цикл" или "еще каки-нибудь операции"
12 дек 13, 16:23    [15283598]     Ответить | Цитировать Сообщить модератору
 Re: begin transaction + цикл while  [new]
hanko_nikita
Member

Откуда:
Сообщений: 71
Glory,
Правильно ли я понял, что для конкретно этой задачи использование пользовательской транзакции - это правильное решение, чтобы уменшить время выполнения запроса?


И еще такой вопрос почему без объявления пользовательской транзакции на более мощном сервере с большим количеством ядер, этот запрос выполняется дольше чем на сервере с меньшим количеством ядер, приблизительно в два раза, как и разница в количестве ядер?
12 дек 13, 16:35    [15283655]     Ответить | Цитировать Сообщить модератору
 Re: begin transaction + цикл while  [new]
Glory
Member

Откуда:
Сообщений: 104751
hanko_nikita
Правильно ли я понял, что для конкретно этой задачи использование пользовательской транзакции - это правильное решение, чтобы уменшить время выполнения запроса?

Вы понимаете разницу между 1 транзакцией и 810 транзакциями ?
Откуда мне знать, что для вас является правильным - отмена всех добавленных записей при сбое или отмена одной добавленнйо записи

hanko_nikita
И еще такой вопрос почему без объявления пользовательской транзакции на более мощном сервере с большим количеством ядер, этот запрос выполняется дольше чем на сервере с меньшим количеством ядер, приблизительно в два раза, как и разница в количестве ядер?

Потому что транзакциям не нужны ядра. Им нужны диски.
12 дек 13, 16:47    [15283716]     Ответить | Цитировать Сообщить модератору
 Re: begin transaction + цикл while  [new]
Mind
Member

Откуда: Лучший город на Земле
Сообщений: 2322
Ramis
может надо попробовать поставить хинты With(nolock)?
7 бед - один ответ?
Это наверное один из самых частых и неправильных советов встречающихся на SQL форумах.
12 дек 13, 22:41    [15285215]     Ответить | Цитировать Сообщить модератору
 Re: begin transaction + цикл while  [new]
Mind
Member

Откуда: Лучший город на Земле
Сообщений: 2322
hanko_nikita
Glory,
То есть это правильно надо заключать цикл в транзакцию? А если в цикле много разных команд на изменения разных таблиц, в этом случае что? А что интересно, есть комп 2 ядра, на которм стоит сервер так на нем без объявления транзакции, выполняется меньше сек., почему так?

Каждая транзакция должна быть физически записана на диск во время COMMIT. Если нет явных транзакций, то создается неявная на каждую команду. Операция записи на диск не быстрая (особенно без кэша). Пока диск не ответит операционной системе, а потом и серверу, что все данные записаны, сервер не может перейти к выполнению следующей команды, а у вас их 810.

На 99% уверен, что на одном из серверов у вас включен кэш записи на диск, а на втором нет, отсюда и тормоза при большом количестве маленьких транзакций. На количество ядер вообще пофигу, у вас все на одном ядре выполняется, да и не является процессор тут узким местом.
12 дек 13, 22:48    [15285239]     Ответить | Цитировать Сообщить модератору
 Re: begin transaction + цикл while  [new]
Алексей Куренков
Member [заблокирован]

Откуда: Москва
Сообщений: 567
hanko_nikita,

Glory правильно же Вам сказал. 1 транзакция пройдет за 1у дисковую операцию, а 810 транзакций пусть маленьких за 810 дисковых операций - вот и разница производительности.
13 дек 13, 09:52    [15286332]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить