UMIhelp

Разработка дополнительного функционала => Custom макросы => Тема начата: b5785 от 14 Апреля 2016, 22:10:06

Название: Почистить справочник в БД
Отправлено: b5785 от 14 Апреля 2016, 22:10:06
Разрослась до огромных размеров БД. Системе около 5 лет. Кастомным макросом удалил ненужные заказы - уменьшилась в 2 раза. Но все равно больше гига. В справочнике "Незарегистрированный пользователь" около 3 млн записей. Записи типа ip  и данные пользователей. Как этот справочник почистить?
// Сначала ищем и сохраняем в массиве все id покупателей, которые нельзя удалять.
$objectTypes = umiObjectTypesCollection::getInstance();
$ObjectTypeId = $objectTypes->getBaseType("emarket", "order");
 
$sel_order = new umiSelection;
$sel_order->addObjectType($ObjectTypeId);
$sel_order->addPropertyFilterIsNotNull($num_order);
$result_order = umiSelectionsParser::runSelection($sel_order); //Массив id объектов
$arr_need_users = array();
             
foreach($result_order as $Id) {
      $object = $objects->getObject($Id);
      $need_user_id = $object->getValue("customer_id");
      $arr_need_users[] = $need_user_id;
}
 
// затем тупо делаем выборку из базы всех покупателей и удаляем только тех,
// которых нет в ранее сохранённом массиве нужных покупателей.
 
$cnt = 1000;
 
$sel_guest = new selector('objects');
$sel_guest->types('object-type')->name('emarket', 'customer');       
$sel_guest->limit(0, $cnt);
$sel_guest->order('id')->desc();
$result_guest = $sel_guest->result();
 
$deleted=0;
foreach($result_guest as $item){
    $id_customer = $item->id;
    if(!in_array($id_customer, $arr_need_users)) {
        $objects->delObject($id_customer);
        //$sql_del = "DELETE FROM `cms3_object_content` WHERE `obj_id` = {$id_customer}";
        //l_mysql_query($sql_del);   
        $deleted++;
    }
}
нешел вот этот пример, но он не работает. ничего не удаляет. перепробывал уже всякие варианты - delObject($id_customer) почемуто не работает.
Название: Re: Почистить справочник в БД
Отправлено: aghigay от 14 Апреля 2016, 22:24:38
Ну скрипт, судя по примеру, пытается удалить пользователей, у которых нет заказов. Собственно видимо проблема в том, что у остальных пользователей заказы есть. Возможно это не совсем адекватные заказы - типа брошенные корзины и все такое. Но все равно они видимо есть и поэтому удаление не работает.

Какая версия юми? Возможно стоит поглядеть в сторону запуска крона, который с некоторых пор как раз и чистит такой мусор.

Ну и еще посмотрите на 3 стандартные проблемы:
1. комментарии
2. события
3. статистика
Название: Re: Почистить справочник в БД
Отправлено: b5785 от 15 Апреля 2016, 09:24:41
Ну скрипт, судя по примеру, пытается удалить пользователей, у которых нет заказов. Собственно видимо проблема в том, что у остальных пользователей заказы есть. Возможно это не совсем адекватные заказы - типа брошенные корзины и все такое. Но все равно они видимо есть и поэтому удаление не работает.

Какая версия юми? Возможно стоит поглядеть в сторону запуска крона, который с некоторых пор как раз и чистит такой мусор.

Ну и еще посмотрите на 3 стандартные проблемы:
1. комментарии
2. события
3. статистика
Версия системы 2.9.6 (несколько раз уже обновлялась)
Комментарии, Статистику, События - все удалил с админ.
Крон пытался ставить, все делал по инструкции, но этот мусор никуда не делся - База нисколько не уменьшилась.
Поэтому решил чистить кастомными макросами.
Пользователей зарег. около 10. Заказов в админ до 10. Все остальное удалил.
Нужно очистить эти 3 млн строк мусора.
Из примера выше делаю массив выборки этих записей, смотрю через var_dump() - все верно, ид как раз этих элементов. только как их удалить?
Название: Re: Почистить справочник в БД
Отправлено: aghigay от 15 Апреля 2016, 11:13:58
Посмотрите на заказы как на справочник и узнаете сколько их реально. Мне кажется, что вы смотрели через модуль ИМ и поэтому не в курсе об их количестве.

Как это сделать:
открываете адрес http://site.ru/admin/data/guide_items/NNN/ где NNN - это идентификатор типа данных заказа. У меня в системе это 24. Какой у вас - нужно смотреть
Название: Re: Почистить справочник в БД
Отправлено: b5785 от 15 Апреля 2016, 11:39:58
заказов пустых 1125. хотя я их только недавно почистил. но не зарег. покупателей действительно 3 млн. откройте справочник "Незарегистрированный покупатель" и посмотрите сколько у вас ? я так понимаю система видит новый ip с которого зашли на сайт и тут же сохраняет его в этот справочник. вот их там и насобиралось.
еще добавлю, смотрю в БД там каждому этому пользователю прикреплено ряд полей из этого типа данных в таб. cms3_object_content, из-за этого и такой огромный размер этой таблицы. и он постоянно растет.
так все таки как это почистить?
Название: Re: Почистить справочник в БД
Отправлено: aghigay от 15 Апреля 2016, 11:46:02
где-то 80 заказов и около 30 незарегистрированных покупателей
Название: Re: Почистить справочник в БД
Отправлено: b5785 от 15 Апреля 2016, 13:10:32
а как принудительно удалить эти элементы? через commit()
Название: Re: Почистить справочник в БД
Отправлено: aghigay от 15 Апреля 2016, 14:27:44
нажать на первом, зажать шифт, нажать на последнем - выделятся все. Правая клавиша - удалить
Название: Re: Почистить справочник в БД
Отправлено: b5785 от 15 Апреля 2016, 14:42:50
Хороший способ. Спасибо. Но это мне придется даже по 100 записей сделать 3000 раз)
Пишу "костыль" прямого удаления через SQL - посмотрим что получится.
Название: Re: Почистить справочник в БД
Отправлено: aghigay от 15 Апреля 2016, 14:44:29
не надо. Это будет убийство связей. Только через селекторы
Название: Re: Почистить справочник в БД
Отправлено: b5785 от 15 Апреля 2016, 14:53:48
стараюсь аккуратно это сделать. отследил эти id в трех таблицах. и со всех буду удалять. потом видно будет.
Я так понимаю, что $objects->delObject($id_customer); это через селектор? но он не удаляет. как это сделать? я пока не знаю. и найти не могу похожих вариантов.
Название: Re: Почистить справочник в БД
Отправлено: aghigay от 15 Апреля 2016, 15:09:10
возможно проблема в том, что ваш скрипт ничего не нашел? Поэтому ничего и не удалил?
Название: Re: Почистить справочник в БД
Отправлено: b5785 от 15 Апреля 2016, 15:16:30
Я уже делал так, нашел в админ id такого пользователя, потом
$id=13145895;
$objects->delObject($id);
echo 'ok';
результата нет, пустая страница. пользователь не удален.
Название: Re: Почистить справочник в БД
Отправлено: aghigay от 15 Апреля 2016, 15:30:32
Лучше весь код скрипта - кусок кода не показателен
Название: Re: Почистить справочник в БД
Отправлено: b5785 от 15 Апреля 2016, 15:34:20
public function getGuideList($id){
$cnt = 1000;
$sel_guest = new selector('objects');
$sel_guest->types('object-type')->name('emarket', 'customer');       
$sel_guest->limit(0, $cnt);
$sel_guest->order('id')->desc();
$result_guest = $sel_guest->result();

$id=13145895; // реальный пользователь, выбран с админ справочник "Незарег. покупатели"
$objects->delObject($id);
echo 'ok';
}
Название: Re: Почистить справочник в БД
Отправлено: aghigay от 15 Апреля 2016, 15:40:48
Ну понятно. А $objects - это кто?

Судя по всему тут слегка не хватает строки
$objects = umiObjectsCollection::getInstance();
Название: Re: Почистить справочник в БД
Отправлено: b5785 от 15 Апреля 2016, 15:52:27
Вот! этого оказывается и не хватало. Код наконец то работает. Спасибо!!!
Название: Re: Почистить справочник в БД
Отправлено: b5785 от 15 Апреля 2016, 16:08:44
Наконец то разобрались, благодаря aghigay. думаю это многим будет полезно если такого мусора много. поэтому от себя еще добавлю - в конец скрипта еще допишите
echo "<html><head><script>
onload = function () {setTimeout ('location.reload (true)', 2000)}
</script></head><body>".($deleted)."</body></html>";
и можно пойти покурить.
ну и в конце еще нужно оптимизировать всю БД.
Название: Re: Почистить справочник в БД
Отправлено: b5785 от 16 Апреля 2016, 13:45:09
Результат: до начала очистки База Данных была около 4 Гиг. После - до 50 Мб.
Название: Re: Почистить справочник в БД
Отправлено: aghigay от 16 Апреля 2016, 18:18:44
:-)