Jump to content

Регулярная очистка статистики


Recommended Posts

Нашёл встроенное решение: опцию “Период автоматического удаления” в настройках статистики. Судя по описанию в справке, статистика должна храниться только установленный период.

 

Думал, что решил вопрос, поставил обновлять статистику раз в месяц, но вот месяц прошел, а статистика всё растёт - что делать?

 

Прошло ещё две недели - никто не ответил. Не верю, что никто эту проблему не решил и все смирились с неограниченно растущей базой. Пусть игнорирование вопросов останется на совести молчащих.

 

Решение нашёл сам, путём расширения уже готовой функции. В файле 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 by carcous (see edit history)
  • Like 1

Share this post


Link to post
Share on other sites

  • 3 months later...

Спасибо Carcous!

Отредактировал свой фаил в соответствии с вышеизложенным - таблицы уменьшелись в ~20 раз.

  cr_connections 478334 -> 26779
  cr_connections_page 682337 -> 35614
  cr_connections_source 622849 -> 31832
 

Правда пришлось поменять интервал статистики с 1 года на 1 месяц.

 

Как говорится:

 

РЕСПЕКТ!

Share this post


Link to post
Share on other sites

  • 5 months later...

:rolleyes: Идея, конечно хорошая. Но каждый раз при записи нового соединения, т.е. при записи в таблицу _connections будут выполняться все эти запросы на удаление. Мне кажется, что это не очень хорошо.

Я вижу 2 варианта:

1. Повесить скрипт на CRON (допустим, 1 раз в месяц или год в зависимости от посетителей)

2. Сделать это вручную (тоже 1 раз в месяц или год в зависимости от посетителей)

 

:rolleyes: Кстати, таблицу _guest можно чистить следующим образом (для Вашего варианта):

После выполнения Ваших запросов находим в таблице _connections минимальное значение в столбце `id_guest`,например 341379 и затем удаляем из таблицы _guest все записи по условию: DELETE FROM `_guest` WHERE ( `id_guest` < 341379 ).

 

:rolleyes: Спасибо за идею!

Edited by subarufor (see edit history)

Share this post


Link to post
Share on other sites

:D Я все-таки решил довести эту идею до ума. Вот что получилось. У меня 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. Затем в Админ панели: Статистика --> Настройки --> Сохранить (чтобы прописались константы).

 

:rolleyes: В итоге получаем автоматическое ежемесячное удаление записей в таблицах статистики. И ежегодную полную очистку этих таблиц.

Edited by subarufor (see edit history)

Share this post


Link to post
Share on other sites

Доработал собственное решение.
В файле 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 by carcous (see edit history)

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

Cookies ensure the smooth running of our services. Using these, you accept the use of cookies. Learn More