Оптимизация таблиц статистики MySQL - PullRequest
9 голосов
/ 25 ноября 2011

Мне нужно создать таблицу в MySQL версии 5.5

эта таблица будет иметь такую ​​информацию, как:

  • пользовательских браузеров (например, Firefox или Chrome)
  • версия браузера (например: 8.0 или 10)
  • IP пользователя
  • дата и время (когда пользователь зашел на сайт)
  • реферер (URL или пусто)

Вот что я думаю:

create table statistics (
 browser varchar(255) not null,
 version float not null,
 ip varchar(40) not null,
 dateandtime datetime,
 referrer varchar(255)
);

Я прочитал на mysql.com , что мне нужно использовать индексы, чтобы сделать мой запрос быстрым, но теперь моя проблема в том, какой индекс я должен создать, чтобы сделать эту таблицу быстрой для запроса?

Мне нужно запросить все поля, например:

  • Я хочу узнать за последние 7 дней, какой браузер пришел на наш сайт и сколько
  • Я хочу знать сегодня, сколько у меня пользователей
  • Я хочу узнать за последний час, какие URL (реферер) мы получили

Спасибо

Ответы [ 3 ]

12 голосов
/ 25 ноября 2011

Я бы порекомендовал это:

Используйте интергеры вместо символов / вариантов. таким образом, вы индексируете быстрее (кроме реферера). Также могу порекомендовать получить сводные таблицы. Хотя это не совсем нормализовано, но запрос будет выполнен мгновенно, особенно если у вас большая организация с большим трафиком.

Итак, вот таблицы:

create table statistics (
 browser tinyint(3) UNSIGNED not null default 0,
 version float(4,2) not null default 0,
 ip INT(10) UNSIGNED not null default 0,
 createdon datetime,
 referrer varchar(5000),
 key browserdate (browser, createdon),
 key ipdate (ip, createdon),
 // etc..
);

browser 0 = неизвестно, 1 = firefox и т. Д. Это можно сделать в вашем коде (поэтому вы загружаете один и тот же код для вставки и выбора). я не использую enum здесь, потому что, если вам нужно изменить таблицу, и у вас есть миллионы записей, это может быть больно. новый браузер = новый номер в коде, который быстрее меняется.

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

Теперь в сводной таблице:

create table statistics_browser_2011_11 (
 browser tinyint(3) UNSIGNED not null default 0,
 version float(4,2) not null default 0,
 number bigint(20) not null default 0,
 createdon datetime,
 unique key browserinfo (createdon, browser, version)
); // browsers stats for november 2011

Таким образом, когда вы вставляете (вы получаете дату пользователя, когда он зашел на сайт и создаете строку $, совпадающую с именем таблицы) в эту таблицу, вы должны использовать только on duplicate key number = number +1. таким образом, когда вы получаете статистику браузера, это очень быстро.

теперь здесь вам нужно будет создать таблицу слияния, потому что, если вы являетесь вторым месяцем и хотите запросить последние 7 дней, вам понадобится таблица текущего месяца и последнего месяца. вот больше информации: http://dev.mysql.com/doc/refman/5.1/en/merge-storage-engine.html

и вы повторяете процесс для получения другой информации: ip, реферер и т.д ...

Чтобы сохранить эти таблицы, вам нужно создать cronjob, который будет создавать таблицы на следующий месяц. простой скрипт PHP, который получает текущий год / месяц, а затем создает таблицу на следующий месяц, если она не существует, а затем объединяет их)

это может быть немного работы, но это то, как я делаю это на работе (с аналогичными данными) с 12 терабайтами данных и 5000 сотрудников, которые выбирают базы данных. мое среднее время загрузки для каждого запроса составляет около 0,60 секунд на запросы.

1 голос
/ 25 ноября 2011

Я думаю, что ваша схема может быть улучшена до

create table statistics
(
  browser enum('Firefox','IE','Opera','Chrome','Safari','Others') not null 
    default 'Others',
   // major browser family only
   // instead of using free-form of varchar

  user_agent text,
   // to store the complete user agents
   // mainly for reference purpose only

  version float not null,
  ip varchar(40) not null,

  dateandtime datetime not null,

  referer varchar(2000)
  // 255 is no sufficient for referer
);

Индексный ключ

  1. создать индекс в браузере, datetime
  2. Использование enum сделает браузер GROUP BY быстрее
  3. если вам нужна информация о версии, то это будет браузер, версия, дата и время
  4. составной ключ на datetime, browser

запрос 1

select browser, count(*) from statistics
where dateandtime between ? and ?
group by browser;

запрос 2

 select count(*) from statistics
 where dateandtime between ? and ?;

запрос 3

 select referer from statistics
 where dateandtime between ? and ?;
0 голосов
/ 22 декабря 2015

СТАТИСТИКА БРАУЗЕРА И ОС ИЗ ПОЛЬЗОВАТЕЛЬСКИХ АГЕНТОВ В MYSQL
-------------------------------------------------- ------------
Допустим, у вас есть таблица MySQL под названием «loginhistory», которая содержит «userid» и «useragent». Чтобы подсчитать, сколько раз определенные ОС встречались в строках агента пользователя, я использовал следующий запрос MySQL:

SELECT OS, COUNT(OS) AS freq FROM 
(SELECT 
 CASE
   WHEN useragent LIKE '%iPad%' THEN 'iPad'
   WHEN useragent LIKE '%iPhone%' THEN 'iPhone'
   WHEN useragent LIKE '%Android%' THEN 'Android'
   WHEN useragent LIKE '%Mac OS X%' THEN 'OS X'
   WHEN useragent LIKE '%X11%' THEN 'Linux'
   WHEN useragent LIKE '%Windows NT 6.3%' THEN 'Windows 8.1'
   WHEN useragent LIKE '%Windows NT 6.2%' THEN 'Windows 8'
   WHEN useragent LIKE '%Windows NT 6.1%' THEN 'Windows 7'
   WHEN useragent LIKE '%Windows NT 6.0%' THEN 'Windows Vista'
   WHEN useragent LIKE '%Windows NT 5.2%' THEN 'Windows Server 2003; Windows XP x64 Edition'
   WHEN useragent LIKE '%Windows NT 5.1%' THEN 'Windows XP'
   WHEN useragent LIKE '%Windows NT 5.0%' THEN 'Windows 2000'
   WHEN useragent LIKE '%Windows NT 4.0%' THEN 'Microsoft Windows NT 4.0'
   WHEN useragent LIKE '%Windows 9' THEN 'Windows 95/98/Millenium'
   WHEN useragent LIKE '%Windows CE' THEN 'Windows CE'
   ELSE 'Other'
 END OS
 FROM loginhistory) AS osses 
GROUP BY OS 
ORDER BY freq DESC

Посредством использования CASE, WHEN, THEN в строке пользовательского агента выполняется поиск определенных элементов и переводится в понятное имя ОС. Внешний запрос затем группирует эти вновь созданные имена ОС и подсчитывает частоту каждой ОС, выводя что-то вроде этого:

+---------------+------+
| OS            | freq |
+---------------+------+
| Windows 7     | 173  |
| Windows 8.1   | 152  |
| iPad          | 63   |
| Windows Vista | 13   |
| OS X          | 10   |
| iPhone        | 8    |
| Android       | 7    |
+---------------+------+
7 rows in set (0.00 sec)

То же самое можно сделать для вычисления частоты браузеров во всех строках user-agent:

SELECT browser, COUNT(browser) AS freq FROM 
(SELECT 
CASE
   WHEN useragent LIKE '%Chrome%' THEN 'Chrome'
   WHEN useragent LIKE '%Safari%' THEN 'Safari'
   WHEN useragent LIKE '%Firefox%' THEN 'Firefox'
   WHEN useragent LIKE '%MSIE 7%' THEN 'IE7'
   WHEN useragent LIKE '%MSIE 8%' THEN 'IE8'
   WHEN useragent LIKE '%MSIE 9%' THEN 'IE9'
   WHEN useragent LIKE '%MSIE 10%' THEN 'IE10'
   WHEN useragent LIKE '%rv:11%' THEN 'IE11'
   ELSE 'Other'
  END browser
  FROM loginhistory) AS browsers 
GROUP BY browser 
ORDER BY freq DESC

Что бы вывести что-то вроде этого:

+---------+------+
| browser | freq |
+---------+------+
| IE7     | 128  |
| IE11    | 119  |
| Chrome  | 83   |
| Safari  | 38   |
| Firefox | 7    |
| IE10    | 4    |
+---------+------+
6 rows in set (0.00 sec)

Эти данные могут быть затем выгружены прямо в библиотеку, такую ​​как Chart.js, которая автоматически создаст круговую диаграмму из данных частоты. Или вы можете рассчитать проценты самостоятельно относительно суммы всех частот.

Если у вас также есть столбец даты или отметки времени рядом с каждой строкой агента пользователя, вы можете добавить предложение WHERE, например, только для отображения статистики операционных систем и браузеров, использованных за последние шесть месяцев.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...