Правила     Закладки     Карма    Календарь    Журналы    Помощь    Поиск    PDA    Чат   
        СМС-ки
   
Пейджер выключен!
 
Фильтр авторов:    показать 
  скрыть
  Ответ в темуСоздание новой темыСоздание опроса

> Статистика (много строк)
balambasik  
 ۩  Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Новичок
*

Профиль
Группа: Пользователь
Сообщений: 43
Пользователь №: 39255
На форуме: 3 года, 2 месяца, 28 дней
Карма: 1




Доброго дня!

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

Есть такая таблица
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 млн. строк. А это уже более менее нормальная скорость.
А юзеру в админке предоставлю возможность удалять "старые" таблици.

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

PMПисьмо на e-mail пользователю
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
T1grOK  
Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Здесь живет
******

Профиль
Группа: Форумчанин
Завсегдатай форума
Сообщений: 2789
Пользователь №: 24406
На форуме: 6 лет, 8 месяцев, 9 дней
Карма: 180




Цитата (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
PMПисьмо на e-mail пользователюСайт пользователя
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
sergeiss  
Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Сидел он, дум великих полон - и вдаль глядел
******

Профиль
Группа: Эксперт
Группа переписки
Сообщений: 15383
Пользователь №: 4190
На форуме: 9 лет, 4 месяца, 20 дней
Карма: 470




Цитата (T1grOK @ 28.01.2017 - 18:01)
секционирование

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

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

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


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

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

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

user posted image
PMICQ
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
balambasik  
 ۩  Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Новичок
*

Профиль
Группа: Пользователь
Сообщений: 43
Пользователь №: 39255
На форуме: 3 года, 2 месяца, 28 дней
Карма: 1




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

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

Подсчитать количество строк (показов) у обьявления с 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

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

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

PMПисьмо на e-mail пользователю
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
sergeiss  
Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Сидел он, дум великих полон - и вдаль глядел
******

Профиль
Группа: Эксперт
Группа переписки
Сообщений: 15383
Пользователь №: 4190
На форуме: 9 лет, 4 месяца, 20 дней
Карма: 470




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

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

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

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

Это сообщение отредактировал sergeiss - 28.01.2017 - 19:33


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

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

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

user posted image
PMICQ
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
balambasik  
 ۩  [x] Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Новичок
*

Профиль
Группа: Пользователь
Сообщений: 43
Пользователь №: 39255
На форуме: 3 года, 2 месяца, 28 дней
Карма: 1




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

Непонятен начальный момент. У меня есть таблица (пустая). Есть поле 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`);


PMПисьмо на e-mail пользователю
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
sergeiss  
Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Сидел он, дум великих полон - и вдаль глядел
******

Профиль
Группа: Эксперт
Группа переписки
Сообщений: 15383
Пользователь №: 4190
На форуме: 9 лет, 4 месяца, 20 дней
Карма: 470




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

Например, вот по этой ссылке пишут
Цитата
Выделение разделов в MySQL оптимизирован для использования с функциям. TO_DAYS() и YEAR(). Однако, Вы можете использовать другие функции даты и времени, которые возвращают целое число или NULL, типа WEEKDAY(), DAYOFYEAR() или MONTH().


Это сообщение отредактировал sergeiss - 28.01.2017 - 22:42


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

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

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

user posted image
PMICQ
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
T1grOK  
Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Здесь живет
******

Профиль
Группа: Форумчанин
Завсегдатай форума
Сообщений: 2789
Пользователь №: 24406
На форуме: 6 лет, 8 месяцев, 9 дней
Карма: 180




Цитата (balambasik @ 28.01.2017 - 18:21)
Нужно создать 365 записей?

Нужно создать, ровно столько партиций, чтобы покрыло все ваши записи в таблице(руками я бы это делать не стал). А новые партиции генерил бы с помощью Event Scheluder, который опирается на тот же cron.
----------
PARTITION BY RANGE (TO_DAYS(date))

Раз уж у вас unixtime, а вы хотите номер дня, то нужно сначала привести unixtime к дате - FROM_UNIXTIME, а потом уже получить номер дня:
TO_DAYS(FROM_UNIXTIME(date))

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

Даты, которые покроют всю вашу таблицу:
...LESS THAN( TO_DAYS('2017-01-01'),
...
LESS THAN( TO_DAYS('2017-01-02'),


--------------------
Mysql, Postgresql, Redis, Memcached, Unit Testing, CI, Kohana, Yii, Phalcon, Zend Framework, Joomla, Open Cart, Ymaps, VK Api
PMПисьмо на e-mail пользователюСайт пользователя
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
  Быстрый ответ
Информация о Госте
Введите Ваше имя
Кнопки кодов
Для вставки цитаты, выделите нужный текст и
НАЖМИТЕ СЮДА
Введите сообщение
Смайлики
:huh:  :o  ;) 
:P  :D  :lol: 
B)  :rolleyes:  <_< 
:)  :angry:  :( 
:unsure:  :blink:  :ph34r: 
     
Показать всё

Опции сообщения  Включить смайлики?
 Включить подпись?
 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:

Опции темы Ответ в темуСоздание новой темыСоздание опроса