Издевательство, издевательство. Из пушки по воробьям палить.
Базы - какого размера? А куда потом помещаются индексы, и что становится со страницами, где размещались старые индексы?
AWE больше 3 гиг не адресует. Это если в boot.ini прописать /3gb. Как-то так. Ни разу не удалось заставить есть больше 3 гиг
Ну... Если по порядку, то у вопрошающего база 8 гиг.
Если запустить ночью ребилд индексов, то по классике сиквел скрупулезно перебирает каждый индекс, дропает его и создает заново, при этом складывает его по порядку ключевых колонок. При этом % заполнения страницы получается примерно такой, как указано в свойствах индекса или в самом переиндексирующем скрипте (скорее всего это дефолтные 100%). В результате получаем некоторое количество освободившихся страниц, которые остаются в базе для будущего использования. И это есть хорошо:
1. строки в индексах выстроены красиво и по порядку. тобишь надо меньше читать при сканах.
2. страницы заполнены на 100% - прочитав одну страницу получаем сразу полные 8к информации
3. страницы идут друг за дружкой, значит при больших сканах головка диска за один заход считывает все сразу по порядку, а не носится как угорелая по всему винту.
4. если нам надо внести дополнительные строки в таблицу, то у нас для этого уже есть пустые страницы, не надо увеличивать размер файла и дополнительно фрагментировать его. разбиение страниц, конечно никто не отменяет при этом.
На самом деле в этой логике есть огрехи для конкретных случаев: заполнение индексов может быть не 100%, физически файл на диске может быть так фрагментирован, что польза от дефрагментации индекса может быть сведена к нулю и т.д.
Но в общем и целом перестройка индексов - лучше их дефрагментации при условии что расходы на перестройку легко выделяются (в первую очередь время, необходимое для перестройки). Если же ваша база работает под напрягом круглосуточно, то путь к ребилду индексов вам заказан ввиду офлайнов и жестких блокировок. Но ведь 99.9% акцентовских баз запросто могут себе позволить пару часиков каждую ночь?
Добавлено: Чт Фев 09, 2012 7:46 am Заголовок сообщения:
AWE, /3GB и пр. прописаны - все равно больше 3ГБ не использует.
Одно время реиндексация была раз в неделю - к концу срока тормозило жутко, перестроил ежедневно (в смысле каждую ночь) - все стало отлично. В моем случае как ресурсов железа, так и ресурсов времени на это хватает с головой, кроме того, уже более 7 лет все именно так нормально функционирует, и поэтому нарушать золотое правило "не мешай механизму работать" я не собираюсь.
И чтобы не создавать новую тему - как Акцент 7.0 уживается с WIN2008R2x64 и, соответственно, с MSSQL2008x64 ? На какие грабли можно наступить?
Добавлено: Чт Фев 09, 2012 8:51 am Заголовок сообщения:
irBis писал(а):
AWE, /3GB и пр. прописаны - все равно больше 3ГБ не использует.
Одно время реиндексация была раз в неделю - к концу срока тормозило жутко, перестроил ежедневно (в смысле каждую ночь) - все стало отлично. В моем случае как ресурсов железа, так и ресурсов времени на это хватает с головой, кроме того, уже более 7 лет все именно так нормально функционирует, и поэтому нарушать золотое правило "не мешай механизму работать" я не собираюсь.
И чтобы не создавать новую тему - как Акцент 7.0 уживается с WIN2008R2x64 и, соответственно, с MSSQL2008x64 ? На какие грабли можно наступить?
1. Золотого правила в SQL не существует. База растет, запросы меняются, распределение данных и статистика меняется. Потому время от времени перемены нужны. Как минимум - проверка эффективности индексов.
2. Да отлично уживается... Никаких особых проблем нет. Для очистки совести можете поставить в тестовом окружении. При этом вы должны понимать, что если у вас база 8 гиг и вы захотите ее как-то оптимизировать, то у вас неизбежно появятся новые индексы и размер вырастет. Т.е. из Express'а вы быстро вырастите.
Добавлено: Пт Мар 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 что бы мастер отчетов учитывал таблицу остатков.
Добавлено: Сб Мар 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 что бы мастер отчетов учитывал таблицу остатков.
Добавлено: Пн Мар 05, 2012 10:00 am Заголовок сообщения:
Идея состоит в том , что данные изменяются часто только за последние 2 месяца.
Также прошу заметить , что оптимизировать можно до бесконечности, но адекватная критика приветствуется .
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 раз
Добавлено: Пн Мар 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 раз
Добавлено: Пн Мар 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
---- Параметр в базе данных перечисление да/нет ( да =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
-- вложенные агенты или выводит всех агентов
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
Вообщем как то так. Можно оптимизировать дальше - создать несколько таблиц , различных по колонкам ( в разрезе аналитики,подшивок ) или по датам ( за два месяца , за прошлый год).
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете голосовать в опросах