Список форумов Акцент Акцент
официальный форум разработчика программы Акцент
 
 FAQFAQ   ПоискПоиск   ПользователиПользователи   ГруппыГруппы   РегистрацияРегистрация 
 ПрофильПрофиль   Войти и проверить личные сообщенияВойти и проверить личные сообщения   ВходВход 

Медленно начинает работать станд. хранимая продцедура
На страницу Пред.  1, 2
 
Начать новую тему   Ответить на тему    Список форумов Акцент -> Акцент 7.0
Предыдущая тема :: Следующая тема  
Автор Сообщение
kris



Зарегистрирован: 12.01.2006
Сообщения: 371

СообщениеДобавлено: Ср Фев 08, 2012 10:26 pm    Заголовок сообщения: Ответить с цитатой

AllexL писал(а):

А как же AWE?

Издевательство, издевательство. Из пушки по воробьям палить.
Базы - какого размера? А куда потом помещаются индексы, и что становится со страницами, где размещались старые индексы?

AWE больше 3 гиг не адресует. Это если в boot.ini прописать /3gb. Как-то так. Ни разу не удалось заставить есть больше 3 гиг Smile
Ну... Если по порядку, то у вопрошающего база 8 гиг.
Если запустить ночью ребилд индексов, то по классике сиквел скрупулезно перебирает каждый индекс, дропает его и создает заново, при этом складывает его по порядку ключевых колонок. При этом % заполнения страницы получается примерно такой, как указано в свойствах индекса или в самом переиндексирующем скрипте (скорее всего это дефолтные 100%). В результате получаем некоторое количество освободившихся страниц, которые остаются в базе для будущего использования. И это есть хорошо:
1. строки в индексах выстроены красиво и по порядку. тобишь надо меньше читать при сканах.
2. страницы заполнены на 100% - прочитав одну страницу получаем сразу полные 8к информации
3. страницы идут друг за дружкой, значит при больших сканах головка диска за один заход считывает все сразу по порядку, а не носится как угорелая по всему винту.
4. если нам надо внести дополнительные строки в таблицу, то у нас для этого уже есть пустые страницы, не надо увеличивать размер файла и дополнительно фрагментировать его. разбиение страниц, конечно никто не отменяет при этом.

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

Но в общем и целом перестройка индексов - лучше их дефрагментации при условии что расходы на перестройку легко выделяются (в первую очередь время, необходимое для перестройки). Если же ваша база работает под напрягом круглосуточно, то путь к ребилду индексов вам заказан ввиду офлайнов и жестких блокировок. Но ведь 99.9% акцентовских баз запросто могут себе позволить пару часиков каждую ночь?
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
irBis
Гость





СообщениеДобавлено: Чт Фев 09, 2012 7:46 am    Заголовок сообщения: Ответить с цитатой

AWE, /3GB и пр. прописаны - все равно больше 3ГБ не использует.
Одно время реиндексация была раз в неделю - к концу срока тормозило жутко, перестроил ежедневно (в смысле каждую ночь) - все стало отлично. В моем случае как ресурсов железа, так и ресурсов времени на это хватает с головой, кроме того, уже более 7 лет все именно так нормально функционирует, и поэтому нарушать золотое правило "не мешай механизму работать" я не собираюсь.
И чтобы не создавать новую тему - как Акцент 7.0 уживается с WIN2008R2x64 и, соответственно, с MSSQL2008x64 ? На какие грабли можно наступить?
Вернуться к началу
kris



Зарегистрирован: 12.01.2006
Сообщения: 371

СообщениеДобавлено: Чт Фев 09, 2012 8:51 am    Заголовок сообщения: Ответить с цитатой

irBis писал(а):
AWE, /3GB и пр. прописаны - все равно больше 3ГБ не использует.
Одно время реиндексация была раз в неделю - к концу срока тормозило жутко, перестроил ежедневно (в смысле каждую ночь) - все стало отлично. В моем случае как ресурсов железа, так и ресурсов времени на это хватает с головой, кроме того, уже более 7 лет все именно так нормально функционирует, и поэтому нарушать золотое правило "не мешай механизму работать" я не собираюсь.
И чтобы не создавать новую тему - как Акцент 7.0 уживается с WIN2008R2x64 и, соответственно, с MSSQL2008x64 ? На какие грабли можно наступить?

1. Золотого правила в SQL не существует. База растет, запросы меняются, распределение данных и статистика меняется. Потому время от времени перемены нужны. Как минимум - проверка эффективности индексов.
2. Да отлично уживается... Никаких особых проблем нет. Для очистки совести можете поставить в тестовом окружении. При этом вы должны понимать, что если у вас база 8 гиг и вы захотите ее как-то оптимизировать, то у вас неизбежно появятся новые индексы и размер вырастет. Т.е. из Express'а вы быстро вырастите.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
APOSTROFF



Зарегистрирован: 07.12.2005
Сообщения: 13

СообщениеДобавлено: Пт Мар 02, 2012 5:28 pm    Заголовок сообщения: Re: Медленно начинает работать станд. хранимая продцедура Ответить с цитатой

irBis писал(а):
Есть такой сабж с именем ap_rep_wiz3. Вызывается он при расчете аммортизации ОС (определение остатка). После нескольких расчетов по разным счетам/группам наступает момент, когда расчет из 100 объектов занимает 3-4 часа. При этом время выполнения данной продцедуры с обычных <=1сек увеличивается до 10-15сек. Помогает только полный рестарт сервера. Каких либо закономерностей не выявил.
Куда копнуть?

ap_rep_wiz3 хранимка запускается мастером отчетов .
Не знаю сейчас, но раньше она очень сильно подвисала если строили данные "на начало" с колонкой "документ". Тут два выхода или отказаться от подобных отчетов - т.е. или "на начало" или колонка "документ".
Но лучше создать таблицу остатков ,( скажем на начало 2012 года) и переписать UDF-ки afn_rw_fields ,afn_rw_from,afn_rw_groupby и afn_rw_where что бы мастер отчетов учитывал таблицу остатков.

Если интересно - могу поделится кодом =)
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
olimp
Site Admin


Зарегистрирован: 10.03.2005
Сообщения: 2661

СообщениеДобавлено: Сб Мар 03, 2012 8:35 am    Заголовок сообщения: Re: Медленно начинает работать станд. хранимая продцедура Ответить с цитатой

APOSTROFF писал(а):
irBis писал(а):
Есть такой сабж с именем ap_rep_wiz3. Вызывается он при расчете аммортизации ОС (определение остатка). После нескольких расчетов по разным счетам/группам наступает момент, когда расчет из 100 объектов занимает 3-4 часа. При этом время выполнения данной продцедуры с обычных <=1сек увеличивается до 10-15сек. Помогает только полный рестарт сервера. Каких либо закономерностей не выявил.
Куда копнуть?

ap_rep_wiz3 хранимка запускается мастером отчетов .
Не знаю сейчас, но раньше она очень сильно подвисала если строили данные "на начало" с колонкой "документ". Тут два выхода или отказаться от подобных отчетов - т.е. или "на начало" или колонка "документ".
Но лучше создать таблицу остатков ,( скажем на начало 2012 года) и переписать UDF-ки afn_rw_fields ,afn_rw_from,afn_rw_groupby и afn_rw_where что бы мастер отчетов учитывал таблицу остатков.

Если интересно - могу поделится кодом =)

Конечно интересно Smile
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Отправить e-mail Посетить сайт автора
APOSTROFF



Зарегистрирован: 07.12.2005
Сообщения: 13

СообщениеДобавлено: Пн Мар 05, 2012 10:00 am    Заголовок сообщения: Ответить с цитатой

Идея состоит в том , что данные изменяются часто только за последние 2 месяца.
Также прошу заметить , что оптимизировать можно до бесконечности, но адекватная критика приветствуется .

пысы: что с отступами ((

Создается таблица :
Код:

CREATE TABLE [dbo].[rest2month] (
   [accid] [int] NULL ,
   [agid] [int] NULL ,
   [entid] [int] NULL ,
   [serid] [int] NULL ,
   [qty] [money] NULL ,
   [suma] [money] NULL
) ON [PRIMARY]
GO

 CREATE  UNIQUE  CLUSTERED  INDEX [IndexRest2Month] ON [dbo].[rest2month]([accid], [entid], [agid], [serid]) ON [PRIMARY]


Создается Job , который будет обновлять таблицу на всякий пожарный каждую ночь .
Разумеется, он также запускается , если внесены изменения в поза-поза-прошлый месяц .

Пример запроса который будет обновлять таблицу:
Код:

delete from rest2month

declare @d datetime, @enddate datetime
set @d = convert(char(8),getdate(),112)
set @enddate = dateadd(month, -2, dateadd(day, 1-day(@d), @d) )

select acc_id
into #acc
from accounts


insert into rest2month(accid, agid, entid, serid, qty, suma)
select accid, agid, entid, serid, isnull(sum(qty),0) as qty, isnull(sum(suma),0) as suma
from
(
   select   acc_db as accid, j_ag1 as agid, j_ent as entid, ser_id as serid,
      sum(j_qty) as qty, sum(j_sum) as suma
   from journal as j  inner join #acc as a on a.acc_id = j.acc_db
   where   j_done = 2 and j_date < @enddate
   group by acc_db, j_ag1, j_ent, ser_id

   union all
      select   acc_cr as accid, j_ag2 as agid, j_ent as entid, ser_id as serid,
      -sum(j_qty) as qty, -sum(j_sum) as suma
   from journal as j inner join #acc as a on a.acc_id = j.acc_cr
   where   j_done = 2 and j_date < @enddate
   group by acc_cr, j_ag2, j_ent, ser_id
) as q


Последний раз редактировалось: APOSTROFF (Пн Мар 05, 2012 10:22 am), всего редактировалось 1 раз
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
APOSTROFF



Зарегистрирован: 07.12.2005
Сообщения: 13

СообщениеДобавлено: Пн Мар 05, 2012 10:14 am    Заголовок сообщения: Ответить с цитатой

Создается универсальная табличная UDF –ка , которая будет принимать на вход параметры :
--@Date - дата по которую невключительно строятся остатки
--@today - дата получаемая getDAte нужна для расчета даты таблицы остатков rest2month
--@AccID - счет по которому строятся остатки
--@AccTreeFlag - признак вложенности счета
--@AgID - корреспондент
--@AgTreeFlag - признак того что корреспондент вложенными с детьми
--@EntID - обьект учета
--@EntTreeFlag - признак того что обьект с вложенными с детьми

и возвращать @RestsSers table ( AgID int , EntID int , Qty Money , Suma Money , SerID int )
Код функции достаточно большой , ну и достаточно прозрачный - поэтому выкладывать его тут не имеет смысла , если кому что интересно могу или выслать или прикрепить тут ( если разберусь как это сделать )

Остатки считаются по принципу
Если @Date >= @RestTableDate :берутся остатки из таблицы и к ним прибавляются обороты от @ RestTableDate до @Date
Если @Date < @RestTableDate and DateDiff(day , @Date , @RestTableDate)<@N
где @N – примерно треть длины базы в днях :
берутся остатки из таблицы и из них вычитаются обороты @Date до @ RestTableDate
В любом другом случае берутся просто обороты от начала базы


Последний раз редактировалось: APOSTROFF (Пн Мар 05, 2012 10:19 am), всего редактировалось 1 раз
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
APOSTROFF



Зарегистрирован: 07.12.2005
Сообщения: 13

СообщениеДобавлено: Пн Мар 05, 2012 10:16 am    Заголовок сообщения: Ответить с цитатой

Для тестового прогона я создал параметр базы банных :
“Ускорение мастера отчетов” тип перечисление – логика

Вот получившийся код ap_rep_wiz3:
Код:

CREATE procedure ap_rep_wiz3
@mask  int      = 1, -- маска
@et    int      = 1, -- тип объекта
@eid   int      = 0, -- ID объекта
@acc   int      = 0, -- ID счета
@crc   int      = 1, -- валюта
@sd    datetime = null,
@ed    datetime = null,
@trn   smallint = 0, -- обороты
@sub   smallint = 0, -- субсчета
@recur smallint = 0, -- рекурсия
@msc1  int      = 0, -- misc number (FIELD)
@msc2  int      = 0, -- misc number (TREE)
@mc    int      = 0 -- my compay
with recompile
as

set nocount on

declare @iscur smallint
declare @sql nvarchar(4000)
declare @prm nvarchar(256)
declare @dst smallint
select @dst = 0
if (@crc = 1) or (@crc = 0)
  select @iscur = 0
else
  select @iscur = 1

if (@sub = 1) or (@recur = 1)
  select @dst = 1

---- Параметр в базе данных перечисление да/нет ( да =58 )
Declare @NewRepWiz int
select @NewRepWiz =
   (   select Isnull(PRM_LONG,  0)
      from DB_PARAM_NAMES with(nolock) inner join DB_PARAMS  with(nolock)
         on DB_PARAM_NAMES.PRM_ID=DB_PARAMS.PRM_ID
      where PRM_NAME = 'Ускорение мастера отчетов'
   )

-- если на начало и валюта – стандарт и нет поля аналитики и строится не по аналитики и нет поля документ и параметр – да
If @trn = 0 and  @iscur = 0 and   (@mask & 16) = 0 and @et <> 4 and @et <> 5  and (@mask & 128) = 0 and @NewRepWiz = 58
 Begin
   select @prm = N'@sd datetime, @ed datetime, @acc int, @eid int, @crc int, @msc1 int, @msc2 int, @mc int'
   select @sql = dbo.afn_rw_fieldsrests(@mask, @iscur, @dst)
   select @sql = @sql + dbo.afn_rw_fromRests(@mask, @iscur, @sub, @et, @recur)
   select @sql = @sql + dbo.afn_rw_whereRests(@mask, @iscur, @trn, @sub, @mc, @et, @recur)
   select @sql = @sql + dbo.afn_rw_groupbyRests(@mask, @iscur, @trn, @sub, @dst)
 end
   else
 begin

   select @prm = N'@sd datetime, @ed datetime, @acc int, @eid int, @crc int, @msc1 int, @msc2 int, @mc int'
   select @sql = dbo.afn_rw_fields(@mask, @iscur, @dst)
   select @sql = @sql + dbo.afn_rw_from(@mask, @iscur, @sub, @et, @recur)
   select @sql = @sql + dbo.afn_rw_where(@mask, @iscur, @trn, @sub, @mc, @et, @recur)
   select @sql = @sql + dbo.afn_rw_groupby(@mask, @iscur, @trn, @sub, @dst)
 end

execute sp_executesql @sql, @prm, @sd, @ed, @acc, @eid, @crc, @msc1, @msc2,  @mc
GO


Последний раз редактировалось: APOSTROFF (Пн Мар 05, 2012 10:21 am), всего редактировалось 1 раз
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
APOSTROFF



Зарегистрирован: 07.12.2005
Сообщения: 13

СообщениеДобавлено: Пн Мар 05, 2012 10:17 am    Заголовок сообщения: Ответить с цитатой

UDF ки :

Код:

-----------------------------------------
CREATE function [dbo].[afn_rw_fieldsRests]
(@mask int, @iscur smallint, @dst smallint) 
returns nvarchar(4000)
as 
begin      
declare @UsName varchar(255)
set @UsName = (SELECT convert(char(30), system_USER))

 declare @sql nvarchar(4000)
 select @sql =  N'declare  @Today DateTime  Set  @Today = GetDAte()   select '   
 -- date
 if (@mask & 1) <> 0
   select @sql = @sql + N'NULL, '
 else
   select @sql = @sql + N'NULL, '
 -- entity
 if (@mask & 8) <> 0
   select @sql = @sql + N' entID as J_ENT, '
 else
   select @sql = @sql + N'0, '
 -- agent
 if (@mask & 4) <> 0
   select @sql = @sql + N'AgID, NULL, '
 else
   select @sql = @sql + N'0, 0, '
 -- series
 if (@mask & 32) <> 0
   select @sql = @sql + N'SerID, '
 else
   select @sql = @sql + N'0, '
 -- docid
 if (@mask & 128) <> 0
   select @sql = @sql + N'0, '
 else
   select @sql = @sql + N'0, '
 -- misc
 if (@mask & 16) <> 0
   select @sql = @sql + N'0,'
 else
   select @sql = @sql + N'0, '
 -- frm
 if (@mask & (1024 + 2048 + 2)) <> 0
   select @sql = @sql + N'0, '
 else
   select @sql = @sql + N'0, '
 -- pdoc
 if (@mask & 64) <> 0
   select @sql = @sql + N'0,'
 else
   select @sql = @sql + N'0, '
 -- docno
 if (@mask & 2) <> 0
   select @sql = @sql + N'NULL, '
 else
   select @sql = @sql + N'NULL, '
 -- name
 if (@mask & 1024) <> 0
   select @sql = @sql + N'NULL, '
 else
   select @sql = @sql + N'NULL, '
 -- memo
 if (@mask & 2048) <> 0
   select @sql = @sql + N'NULL, '
 else
   select @sql = @sql + N'NULL, '

 select @sql = @sql + N'@acc, NULL, '

 if @dst = 1

   --661 счет, 6511, 652, 653, 654, 655, 656, 4711, 4712
       select @sql = @sql + N'sum(distinct Suma), '
 else

   --661 счет, 6511, 652, 653, 654, 655, 656, 4711, 4712
     select @sql = @sql + N'sum(Suma), '
 if @iscur = 1
   begin
     if @dst = 1
       select @sql = @sql + N'0, '
     else
       select @sql = @sql + N'0, '
   end
  else
   select @sql = @sql + N'cast(0 as money), '
 if @dst = 1
    select @sql = @sql + 'sum(distinct Qty) '
 else

    select @sql = @sql + 'sum(Qty) '
 return @sql
end


Код:

-----------------------------------------
CREATE function [dbo].[afn_rw_fromRests]
(@mask int, @iscur smallint, @sub smallint, @et int, @rcs smallint) 
returns nvarchar(4000)
as 
begin
 declare @sql nvarchar(4000)

 select @sql =  N' from RestsSers(@sd,@Today,@acc,  '   


 if @sub = 1 -- рекурсивно по счетам
   select @sql = @sql + N'1, '
 else
   select @sql = @sql + N'0, '
-- фильтр по агенту
  if @et = 2
    select @sql = @sql + N'@eid, '
  else
    select @sql = @sql + N'0,'

-- вложенные агенты или выводит всех агентов
  if ( @rcs = 1 and @et = 2 )  or ( (@mask & 4) <> 0 and @et<>2 )
   select @sql = @sql + N'1, '
 else
   select @sql = @sql + N'0, '
-- фильтр по обьекту
  if @et = 3
    select @sql = @sql + N'@eid, '
  else
    select @sql = @sql + N'0,'

-- вложенные обьекты  или выводит все обьекты
  if ( @rcs = 1 and @et =3 )  or ( (@mask & 8) <> 0 and @et<>3 )
   select @sql = @sql + N'1, '
 else
   select @sql = @sql + N'0, '   
  -- партии
   if ( @mask & 32 <> 0)   
      select @sql = @sql + N'1) '
   else
    select @sql = @sql + N'0) '
 return @sql
end


Код:

-----------------------------------------
CREATE function [dbo].[afn_rw_groupbyRests]
(@mask int, @iscur smallint, @trn smallint, @sub smallint, @dst smallint) 
returns nvarchar(4000)
as 
begin
 declare @sql nvarchar(4000)
 select @sql = N'  '

 -- agent
  if ( @mask&4<>0 )   
  begin
     select @sql = N'group by AgID '
       if ( @mask&8<>0 )         select @sql = @sql + N',EntID '  -- ent
       if ( @mask&32<>0 )         select @sql = @sql + N',SerID ' ---партия
  end
  else
  begin
    if  ( @mask&8<>0 )
    begin
      select @sql = N'group by  EntID '
       if ( @mask&32<>0 )         select @sql = @sql + N',SerID ' ---партия
    end
    else
       if ( @mask&32<>0 )         select @sql = N'group by SerID ' ---партия
  end
 
 return @sql
end


Код:

-----------------------------------------
CREATE function [dbo].[afn_rw_whereRests]
(@mask int, @iscur smallint, @trn smallint, @sub smallint, @mc int, @et int, @rcs smallint) 
returns nvarchar(4000)
as 
begin
 declare @sql nvarchar(4000)
 select @sql =  N''   
 return @sql
end

Вообщем как то так. Можно оптимизировать дальше - создать несколько таблиц , различных по колонкам ( в разрезе аналитики,подшивок ) или по датам ( за два месяца , за прошлый год).
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Показать сообщения:   
Начать новую тему   Ответить на тему    Список форумов Акцент -> Акцент 7.0 Часовой пояс: GMT + 2
На страницу Пред.  1, 2
Страница 2 из 2

 
Перейти:  
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах


Powered by phpBB © 2001, 2005 phpBB Group