[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Статистика (много строк)
balambasik
Доброго дня!

Столкнулся с проблемой сохранения статистики. Длительный гуглинг показал что простого и красивого решения данной проблемы не существует.

Есть такая таблица
user posted image

В таблице храниться статистика которую потом нужно смотреть и группировать примерно такими запросами

SELECT dev_type, COUNT(dev_type) FROM `views` WHERE camp_id = 10 AND date > 20170116 GROUP BY dev_type ORDER BY dev_type ASC


В тестовой таблице 10 млн. строк
Выполнение такого запроса около 3 секунд, учетом того что у меня SSD и проиндексированы все поля (индексы весят больше самой таблицы)

Вот такой запрос выполняется побыстрее (0.3 секунды)
SELECT ad_id, COUNT(ad_id) FROM `views` WHERE camp_id = 10 AND date = 20170117 GROUP BY ad_id ORDER BY ad_id ASC



Вобщем приходит на ум только одно.
Статистика мне нужна с детализацией по дням (часы, минуты ненужны)

Думаю создавать для каждого дня новую таблицу, такого типа views_stat_2017_01_30 и писать стату в нее.

По моим подсчетам за один день в таблице будет не более 1 млн. строк. А это уже более менее нормальная скорость.
А юзеру в админке предоставлю возможность удалять "старые" таблици.

Не будет ли это *овнорешением проблемы?

T1grOK
Цитата (balambasik @ 28.01.2017 - 09:44)
Думаю создавать для каждого дня новую таблицу, такого типа views_stat_2017_01_30 и писать стату в нее.

Разработчики СУБД уже давно все придумали и фича называется - секционированием.

К тому же, раз уж минимальная детализация "день", то можно добавить таблицу, где все будет уже в необходимой агрегации.

_____________
Mysql, Postgresql, Redis, Memcached, Unit Testing, CI, Kohana, Yii, Phalcon, Zend Framework, Joomla, Open Cart, Ymaps, VK Api
sergeiss
Цитата (T1grOK @ 28.01.2017 - 18:01)
секционирование

Уточню только, что более правильно будет сказать "партицирование"; по-английски partitioning.

balambasik, я вот тут http://phpforum.su/index.php?showtopic=84298 много писал на эту тему.

Как уже верно заметил T1grOK, можно использовать другую таблицу (можно с партициями), куда писать уже агрегированные данные. Например, раз в сутки (где-то ночью) запускаешь специальный скрипт, который суммирует всё, что нужно, и пишет в ту самую "другую" таблицу. В итоге у тебя в запросе будет задействовано относительно немного строк.


_____________
* Хэлп по PHP
* Описалово по JavaScript
* Хэлп и СУБД для PostgreSQL

* Обучаю PHP, JS, вёрстке. Интерактивно и качественно. За разумные деньги.

* "накапливаю умение телепатии" (С) и "гуглю за ваш счет" (С)

user posted image
balambasik
Как я понял партицирование не позволит применять фильтры к статистике.

Например отобразить:

Подсчитать количество строк (показов) у обьявления с ad_id = 15
если geo = ru
если dev_os = 5
если dev_browser = 15


Подсчитать количество строк (показов) блока с block_id = 5
если geo = ru, ua ...
если dev_os = 5, 7, 12
если dev_browser = 15

У меня статистика будет с применением множества таких фильтров.

Я не могу понять как еще (кроме построчной записи каждого показа) можно сохранить данные что бы потом их можно было смотреть с такими фильтрами.

sergeiss
Цитата (balambasik @ 28.01.2017 - 19:05)
Как я понял партицирование не позволит применять фильтры к статистике.

Очень даже позволяет.

Как я понял, со своей стороны, у тебя будет статистика за какой-то период времени или даже за определенную дату. Делаешь партицирование по неделям или месяцам, в зависимости от объема данных. И тогда в выборке будут участвовать не все данные, а только те партиции, которых это касается. Используй тут любые фильтры, нет проблем.

Партицирование - это просто дробление данных на куски по каким-то критериям. При этом, с одной стороны, сохраняется единообразность данных, а с другой стороны, в выборке участвуют только те партиции, которых это касается. То есть, например, если у тебя есть данные за 3 последних года, с партицированием помесячно, а проанализировать надо последние полтора месяца, то будут задействованы только 2 части из 36 - остальные просто никак не будут участвовать. При больших объемах данных это очень сильно ускоряет выборку.

_____________
* Хэлп по PHP
* Описалово по JavaScript
* Хэлп и СУБД для PostgreSQL

* Обучаю PHP, JS, вёрстке. Интерактивно и качественно. За разумные деньги.

* "накапливаю умение телепатии" (С) и "гуглю за ваш счет" (С)

user posted image
balambasik
Почитал про партицирование. Вроде бы то что нужно.

Непонятен начальный момент. У меня есть таблица (пустая). Есть поле date - unix time.
Вот я хочу разбить всю таблицу на куски по дням. Но таблица еще пустая. Как?

Нужно создать 365 записей?
PARTITION BY RANGE (TO_DAYS(date))
(

что писать тут?
PARTITION p0 VALUES LESS THAN( TO_DAYS(' ? ') ),
);


В общем слегка непонятно. Пуду крайне признателен за помощь.
Вот моя таблица как мне добавить партиции по дням?


CREATE TABLE IF NOT EXISTS `views` (
`id` int(11) NOT NULL,
`site_id` int(11) NOT NULL,
`block_id` int(11) NOT NULL,
`camp_id` int(11) NOT NULL,
`ad_id` int(11) NOT NULL,
`dev_type` int(11) NOT NULL,
`dev_os` int(11) NOT NULL,
`dev_browser` int(11) NOT NULL,
`geo` int(11) NOT NULL,
`ip` int(11) unsigned NOT NULL,
`date` int(11) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8


ALTER TABLE `views`
ADD PRIMARY KEY (`id`),
ADD KEY `site_id` (`site_id`),
ADD KEY `block_id` (`block_id`),
ADD KEY `camp_id` (`camp_id`),
ADD KEY `ad_id` (`ad_id`),
ADD KEY `dev_type` (`dev_type`),
ADD KEY `dev_os` (`dev_os`),
ADD KEY `dev_browser` (`dev_browser`),
ADD KEY `geo` (`geo`),
ADD KEY `ip` (`ip`),
ADD KEY `date` (`date`);


Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.