carcous Posted January 22, 2014 Share Posted January 22, 2014 (edited) Нашёл встроенное решение: опцию “Период автоматического удаления” в настройках статистики. Судя по описанию в справке, статистика должна храниться только установленный период. Думал, что решил вопрос, поставил обновлять статистику раз в месяц, но вот месяц прошел, а статистика всё растёт - что делать? Прошло ещё две недели - никто не ответил. Не верю, что никто эту проблему не решил и все смирились с неограниченно растущей базой. Пусть игнорирование вопросов останется на совести молчащих. Решение нашёл сам, путём расширения уже готовой функции. В файле classes/Connection.php есть функция cleanConnectionsPages(), которая вызывается при добавлении нового соединения функцией setNewConnection($cookie). В функции cleanConnectionsPages() очищается только одна таблица: connections_page, удаляются все строки до начала текущего периода автоматического удаления (см. вверху поста). Т.о., процессом удаления база не нагружается каждый раз - это происходит только в начале периода. Но есть и недостаток: в начале периода база будет совсем пустая.Итак, я дописал строки для удаления остальных таблиц: connections и connections_source, pagenotfound, sekeyword. Получилось так: // Records of connections details older than the beginning of the specified interval are deleted Db::getInstance()->execute(' DELETE FROM `'._DB_PREFIX_.'connections` WHERE date_add < LAST_DAY(DATE_SUB(NOW(), INTERVAL '.$interval.'))'); Db::getInstance()->execute(' DELETE FROM `'._DB_PREFIX_.'connections_page` WHERE time_start < LAST_DAY(DATE_SUB(NOW(), INTERVAL '.$interval.'))'); Db::getInstance()->execute(' DELETE FROM `'._DB_PREFIX_.'connections_source` WHERE date_add < LAST_DAY(DATE_SUB(NOW(), INTERVAL '.$interval.'))'); Db::getInstance()->execute(' DELETE FROM `'._DB_PREFIX_.'statssearch` WHERE date_add < LAST_DAY(DATE_SUB(NOW(), INTERVAL '.$interval.'))'); Db::getInstance()->execute(' DELETE FROM `'._DB_PREFIX_.'pagenotfound` WHERE date_add < LAST_DAY(DATE_SUB(NOW(), INTERVAL '.$interval.'))'); Db::getInstance()->execute(' DELETE FROM `'._DB_PREFIX_.'sekeyword` WHERE date_add < LAST_DAY(DATE_SUB(NOW(), INTERVAL '.$interval.'))'); Есть ещё растущая таблица guest, но в ней нет поля date_add с датой-временем, по времени не отобрать. Edited February 28, 2014 by carcous (see edit history) 1 Link to comment Share on other sites More sharing options...
sassbar Posted May 8, 2014 Share Posted May 8, 2014 Спасибо Carcous! Отредактировал свой фаил в соответствии с вышеизложенным - таблицы уменьшелись в ~20 раз. cr_connections 478334 -> 26779 cr_connections_page 682337 -> 35614 cr_connections_source 622849 -> 31832 Правда пришлось поменять интервал статистики с 1 года на 1 месяц. Как говорится: РЕСПЕКТ! Link to comment Share on other sites More sharing options...
subarufor Posted October 30, 2014 Share Posted October 30, 2014 (edited) Идея, конечно хорошая. Но каждый раз при записи нового соединения, т.е. при записи в таблицу _connections будут выполняться все эти запросы на удаление. Мне кажется, что это не очень хорошо. Я вижу 2 варианта: 1. Повесить скрипт на CRON (допустим, 1 раз в месяц или год в зависимости от посетителей) 2. Сделать это вручную (тоже 1 раз в месяц или год в зависимости от посетителей) Кстати, таблицу _guest можно чистить следующим образом (для Вашего варианта): После выполнения Ваших запросов находим в таблице _connections минимальное значение в столбце `id_guest`,например 341379 и затем удаляем из таблицы _guest все записи по условию: DELETE FROM `_guest` WHERE ( `id_guest` < 341379 ). Спасибо за идею! Edited October 30, 2014 by subarufor (see edit history) Link to comment Share on other sites More sharing options...
subarufor Posted November 5, 2014 Share Posted November 5, 2014 (edited) Я все-таки решил довести эту идею до ума. Вот что получилось. У меня PrestaShop 1.4.7.3 1. В файл admin/tabs/AdminStatsConf.php в функцию добавил 2 константы: public function postProcess() { if (Tools::getValue('submitSettings')) { // Константы для периодической очистки таблиц статистики Configuration::updateValue('PS_STATSDATA_NEW_YEAR', date('Y')); Configuration::updateValue('PS_STATSDATA_NEW_MONTH', date('m')); if ($this->tabAccess['edit'] === '1') $this->_postConfig($this->_fieldsSettings); else $this->_errors[] = Tools::displayError('You do not have permission to edit here.'); } } 2. В класс classes/Connection.php добавил новую функцию: public static function cleanStatisticsDatas() { $period_year = Configuration::get('PS_STATSDATA_NEW_YEAR'); $period_month = Configuration::get('PS_STATSDATA_NEW_MONTH'); if ($period_year != date('Y')) { Configuration::updateValue('PS_STATSDATA_NEW_YEAR', date('Y')); Configuration::updateValue('PS_STATSDATA_NEW_MONTH', date('m')); // Полная очистка таблиц статистики за прошлый год (делается автоматически в начале года) Db::getInstance()->execute('TRUNCATE `'._DB_PREFIX_.'connections`'); Db::getInstance()->execute('TRUNCATE `'._DB_PREFIX_.'connections_page`'); Db::getInstance()->execute('TRUNCATE `'._DB_PREFIX_.'connections_source`'); Db::getInstance()->execute('TRUNCATE `'._DB_PREFIX_.'guest`'); Db::getInstance()->execute('TRUNCATE `'._DB_PREFIX_.'pagenotfound`'); Db::getInstance()->execute('TRUNCATE `'._DB_PREFIX_.'sekeyword`'); Db::getInstance()->execute('TRUNCATE `'._DB_PREFIX_.'statssearch`'); return; } if ($period_month != date('m')) { // Будут удаляться записи из таблиц за ПОЗАПРОШЛЫЙ месяц $interval_m = '2 MONTH' // Если дата 2014-11-01 00:02:32, то будут удалены записи ранее, чем 2014-10-01 00:00:00 // Если необходимо удалять записи за ПРОШЛЫЙ месяц, то лучше использовать TRUNCATE или $interval_m = '1 MONTH' // Если очень много посетителей в месяц, то лучше использовать TRUNCATE (иначе процесс займет много времени) $interval_m = '2 MONTH'; $interval_d = '1 DAY'; Configuration::updateValue('PS_STATSDATA_NEW_MONTH', date('m')); // Получем массов индексов 'id_guest', которые будут удалены $result = Db::getInstance()->ExecuteS(' SELECT `id_guest` FROM `'._DB_PREFIX_.'connections` WHERE date_add < DATE_ADD(LAST_DAY(DATE_SUB(NOW(), INTERVAL '.$interval_m.')), INTERVAL '.$interval_d.')'); // Удаляем записи таблиц статистики за ПОЗАПРОШЛЫЙ месяц Db::getInstance()->execute(' DELETE FROM `'._DB_PREFIX_.'connections` WHERE date_add < DATE_ADD(LAST_DAY(DATE_SUB(NOW(), INTERVAL '.$interval_m.')), INTERVAL '.$interval_d.')'); Db::getInstance()->execute(' DELETE FROM `'._DB_PREFIX_.'connections_page` WHERE date_add < DATE_ADD(LAST_DAY(DATE_SUB(NOW(), INTERVAL '.$interval_m.')), INTERVAL '.$interval_d.')'); Db::getInstance()->execute(' DELETE FROM `'._DB_PREFIX_.'connections_source` WHERE date_add < DATE_ADD(LAST_DAY(DATE_SUB(NOW(), INTERVAL '.$interval_m.')), INTERVAL '.$interval_d.')'); Db::getInstance()->execute(' DELETE FROM `'._DB_PREFIX_.'pagenotfound` WHERE date_add < DATE_ADD(LAST_DAY(DATE_SUB(NOW(), INTERVAL '.$interval_m.')), INTERVAL '.$interval_d.')'); Db::getInstance()->execute(' DELETE FROM `'._DB_PREFIX_.'sekeyword` WHERE date_add < DATE_ADD(LAST_DAY(DATE_SUB(NOW(), INTERVAL '.$interval_m.')), INTERVAL '.$interval_d.')'); Db::getInstance()->execute(' DELETE FROM `'._DB_PREFIX_.'statssearch` WHERE date_add < DATE_ADD(LAST_DAY(DATE_SUB(NOW(), INTERVAL '.$interval_m.')), INTERVAL '.$interval_d.')'); // Занимает дополнительно время около 5 - 20 сек (в зависимости от числа посетителей за месяц) foreach ($result as $elem) { // Удаление записей в таблице ps_guest Db::getInstance()->execute(' DELETE FROM `'._DB_PREFIX_.'guest` WHERE (id_guest = '.$elem['id_guest'].')'); } return; } } Затем в этом же классе в функцию public static function setNewConnection($cookie) после строк: Connection::cleanConnectionsPages(); добавил вызов новой функции: Connection::cleanStatisticsDatas(); 3. Затем в Админ панели: Статистика --> Настройки --> Сохранить (чтобы прописались константы). В итоге получаем автоматическое ежемесячное удаление записей в таблицах статистики. И ежегодную полную очистку этих таблиц. Edited November 5, 2014 by subarufor (see edit history) Link to comment Share on other sites More sharing options...
carcous Posted November 9, 2014 Author Share Posted November 9, 2014 (edited) Доработал собственное решение.В файле classes/Connection.php оставляем очистку только трёх таблиц: statssearch, pagenotfound и sekeyword: if ($interval != null) { Db::getInstance()->execute(' DELETE FROM `'._DB_PREFIX_.'statssearch` WHERE date_add < LAST_DAY(DATE_SUB(NOW(), INTERVAL '.$interval.'))'); Db::getInstance()->execute(' DELETE FROM `'._DB_PREFIX_.'pagenotfound` WHERE date_add < LAST_DAY(DATE_SUB(NOW(), INTERVAL '.$interval.'))'); Db::getInstance()->execute(' DELETE FROM `'._DB_PREFIX_.'sekeyword` WHERE date_add < LAST_DAY(DATE_SUB(NOW(), INTERVAL '.$interval.'))'); } и создаём отдельный php-файл (например, в админской папке) с таким содержимым: <?php define('_PS_ADMIN_DIR_', getcwd()); include(_PS_ADMIN_DIR_.'/../config/config.inc.php'); ini_set('max_execution_time', 7200); Db::getInstance()->execute(' DELETE g FROM `'._DB_PREFIX_.'guest` g WHERE g.id_customer=0'); Db::getInstance()->execute(' DELETE c FROM `'._DB_PREFIX_.'connections` c LEFT JOIN `'._DB_PREFIX_.'guest` g ON g.id_guest = c.id_guest WHERE g.id_guest IS NULL'); Db::getInstance()->execute(' DELETE cs FROM `'._DB_PREFIX_.'connections_source` cs LEFT JOIN `'._DB_PREFIX_.'connections` c ON c.id_connections = cs.id_connections WHERE c.id_connections IS NULL'); ?> Этот файл вписываем в cron и запускаем с любой желаемой периодичностью. Смысл файла в том, что из таблицы guest удаляются все, кто не захотел стать клиентом.Потом все эти несознательные граждане удаляются из таблиц connections и connections_source. Удаление происходит по списку пользователей, а не по времени доступа, т. о. покупатели останутся в базе, как бы давно они не регистрировались. Edited November 9, 2014 by carcous (see edit history) Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now