AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
DAX
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 22.04.2010, 18:40   #1  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,429 / 1772 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от sukhanchik Посмотреть сообщение
попытаться бить на отдельные транзакции
И даже тогда можно не отказываться от преимуществ конструкции delete_from. 'Порционного' удаления можно добиться при помощи фильтрации.
X++:
SALESTABLE_TONTRA40478 Table;
date month = 01\03\2010;
RecId minRecId, maxRecId, fromRecId, toRecId;
int partSize = 10000 // Число подобрать надо;

select minof(RecId) from Table where Table.month == month;
fromRecId = Table.RecId;

select maxof(RecId) from Table where Table.month == month;
toRecId = Table.RecId;

for(fromRecId = minRecId; fromRecId <= maxRecId;  fromRecId += partSize)
{
    toRecId = fromRecId + partSize;
    
    Table.skipDatabaseLog(true);
    Table.skipDeleteActions(true);
    Table.skipDeleteMethod(true)
    delete_from Table 
    where 
        Table.month == month &&        
        Table.RecId >= fromRecId &&
        Table.RecId <= toRecId;
}
Старый 22.04.2010, 18:47   #2  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Сложно то как
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
'Порционного' удаления можно добиться при помощи фильтрации.
Да. Но брать порциями по PartSize - бесполезно. В интервале может быть и 10тыс записей, и ни одной. Достаточно просто сузить диапазон.

А главное - обрамить tts-скобками

X++:
SALESTABLE_TONTRA40478 Table;
date month;

while(true)
{
    select minof(month),minof(recid) from Table;
    if( !Table.recid ) break;

    month = Table.month;

    ttsbegin;
    Table.skipDatabaseLog(true);
    Table.skipDeleteActions(true);
    Table.skipDeleteMethod(true)
    delete_from Table 
    where 
        Table.month == month;
    ttscommit;
}
__________________
полезное на axForum, github, vk, coub.
Старый 22.04.2010, 19:10   #3  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,429 / 1772 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от mazzy Посмотреть сообщение
Сложно то как
Зато универсально. Таким способом можно удалить любую другую выборку.

Цитата:
Сообщение от mazzy Посмотреть сообщение
Да. Но брать порциями по PartSize - бесполезно. В интервале может быть и 10тыс записей, и ни одной.
Идея в том что их гарантированно не будет больше 10тыс. Те таблица если и будет заблокированна то не на долго. А если цикл прогонит пару итераций в холостую, что ж с того?

Цитата:
Сообщение от mazzy Посмотреть сообщение
Достаточно просто сузить диапазон
На сколько я понял условие задачи. Удаляють нужно не все записи из таблицы, а только за определённый месяц. Причём даже за один месяц число записей > 600 000;

Цитата:
Сообщение от mazzy Посмотреть сообщение
А главное - обрамить tts-скобками
Зачем? Или это шутка юмора такая?
Старый 22.04.2010, 19:16   #4  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
Идея в том что их гарантированно не будет больше 10тыс. Те таблица если и будет заблокированна то не на долго. А если цикл прогонит пару итераций в холостую, что ж с того?
Может быть и так...
Но может быть просто поискать другое поле? Которое и с индексом, и дает относительно небольшое число записей? Например, не месяц, а дату.

Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
Зачем? Или это шутка юмора такая?
Нет.
Если база установлена в Recovery Model = Full, то разницы действительно не будет.
Если же база установлена в Recovery Model = Simple, то после окончания каждой транзакции transaction log будет очищаться.

вполне возможно, что у автора transaction log сильно растет, а на диске места свободного мало. Вот и мучается SQL, затрачивая каждый раз много времени на увеличение transaction log.
__________________
полезное на axForum, github, vk, coub.
Старый 22.04.2010, 19:20   #5  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,429 / 1772 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от sukhanchik Посмотреть сообщение
далеко не всегда существует индекс в котором бы было единственное поле - RecID
Уточню. Необходим индекс, где поле - RecID стоит на первом месте.

И да, естественно, включать индекс по RecId будет необходимо.

Цитата:
Сообщение от mazzy Посмотреть сообщение
после окончания каждой транзакции transaction log будет очищаться
Это понятно, я просто рассчитывал, что конструкция delete_from cамостоятельно открывает и закрывает транзакцию.
За это сообщение автора поблагодарили: mazzy (2).
Старый 22.04.2010, 19:21   #6  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
Это понятно, я просто рассчитывал, что конструкция delete_from cамостоятельно открывает и закрывает транзакцию.
Э-э-э... По-моему, нет. Хотя могу ошибаться.
__________________
полезное на axForum, github, vk, coub.
Старый 23.04.2010, 10:46   #7  
Zabr is offline
Zabr
Участник
Axapta Retail User
 
1,201 / 345 (14) ++++++
Регистрация: 26.06.2002
Адрес: Москва
В течение полутора лет ежедневно выполняется аналогичная задача, общее количество удаляемых записей сейчас порядка 500 тыс.ежедневно, удаление идет блоками с фиксированным числом записей точно так как выше написал sukhanchik. Попробовал сделать через delete_from c отключением skipDatabaseLog(true), skipDeleteActions(true), skipDeleteMethod(true) как написал lev - стало удаляться быстрее примерно в 4-5 раз. Отличный совет, респект. Блокировок и зависаний нет, т.к. делается не один delete_from на весь массив записей, а отдельными транзакциями по складам магазинов (около 40).
Старый 22.04.2010, 19:00   #8  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,283 / 3491 (123) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
И даже тогда можно не отказываться от преимуществ конструкции delete_from. 'Порционного' удаления можно добиться при помощи фильтрации.
У фильтрации есть тот минус, что по фильтруемому полю нужно иметь адекватный индекс, дабы фильтрация состоялась в ожидаемое время, а не произошел бы Full Table Scan. А далеко не всегда существует индекс в котором бы было единственное поле - RecID.
Конечно брать тупо по 10 (20,30) тыс. записей - тоже не вариант - объем записей бывает разный.
В общем - надо искать "золотую" середину.
__________________
Возможно сделать все. Вопрос времени
За это сообщение автора поблагодарили: mazzy (2).
Старый 22.04.2010, 19:02   #9  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от sukhanchik Посмотреть сообщение
У фильтрации есть тот минус, что по фильтруемому полю нужно иметь адекватный индекс, дабы фильтрация состоялась в ожидаемое время, а не произошел бы Full Table Scan.
Тоже верно!
причем в сообщении автора условие по этом полю и было. вполне возможно, что проблема с отсутствии индекса и в Full Table Scan.
__________________
полезное на axForum, github, vk, coub.
Теги
ax2009, ccadoconnection, delete_from, оптимизация, удаление

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Задвоение RecId при вставке записей через COM коннектор db DAX: Программирование 1 23.04.2009 15:12
Класс OfficialsServ_RU - удаление записей из OfficialsTrans_RU Logger DAX: Программирование 3 14.09.2006 15:58
Запуск программы из Аксапты через 2-хзвенку Migel_84 DAX: Программирование 25 27.04.2006 09:41
Проблема с запуском business connector'a через удал доступ yooshi DAX: Программирование 1 07.11.2005 08:56
Удаление записей из InventDim и SalesTable DreamCreator DAX: Программирование 4 08.12.2004 17:23

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 07:29.
Powered by vBulletin® v3.8.5. Перевод: zCarot
Контактная информация, Реклама.