Оптимизация таблиц статистики MySQL
Мне нужно создать таблицу в 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 ответов
Я бы порекомендовал этот:
используйте intergers вместо chars / varchars. таким образом, вы индексируете быстрее (кроме реферера). Кроме того, я могу рекомендовать получить сводные таблицы. Хотя это не совсем нормализовано, но запрос будет выполнен мгновенно-особенно если у вас большая организация с большим трафиком.
вот таблицы:
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..
);
браузер 0 = неизвестный, 1 = firefox и т. д.. Это можно сделать в вашем коде (поэтому вы загружаете тот же код для вставка и выбор). я не использую enum здесь, потому что если вам нужно изменить таблицу, и у вас есть миллионы записей, это может быть больно. новый браузер = новый номер в коде, который быстрее меняется.
эта таблица может быть использована для resummarized все остальные таблицы, если что-то случится. таким образом, вы создаете индекс для встроенной сводной таблицы (пример браузера)
Теперь сводная таблица:
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
таким образом, когда вы вставляете (вы получаете дату пользователь, когда он получил доступ к сайту и создал $ string, который соответствует имени таблицы) в этой таблице вам нужно использовать только on duplicate key number = number +1
. таким образом, когда вы получаете статистику браузера супер быстро.
Теперь здесь вам нужно будет создать таблицу слияния, потому что если вы второй месяц, и вы хотите запросить последние 7 дней, вам понадобится текущий месяц и таблица последнего месяца. вот Подробнее: http://dev.mysql.com/doc/refman/5.1/en/merge-storage-engine.html
и вы повторяете процесс для другой информации: ip, referrer etc...
чтобы поддерживать эти таблицы, вам нужно будет создать cronjob, который создает таблицы на следующий месяц. простой PHP скрипт, который получает текущий год / месяц, а затем создает таблицу на следующий месяц, если она не существует, а затем объединяет их)
это может быть немного работы, но это как я это делаю на работе (с аналогичными данными) с 12 терабайтами данных и 5000 сотрудников, которые получают базы данных. мое среднее время загрузки для каждого запроса составляет около 0,60 секунды на запросы.
Я думаю, что ваша схема может быть улучшена до
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
);
ключевой индекс
- создайте индекс в браузере, datetime
- использование перечисления сделает группу браузера быстрее
- если вам нужна информация о версии, то это будет браузер, версия, дата
- составной ключ на
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 ?;
СТАТИСТИКА БРАУЗЕРА И ОС ИЗ СТРОК USER-AGENT В MYSQL
--------------------------------------------------------------
Предположим, у вас есть таблица MySQL под названием "loginhistory", которая содержит "userid" и "useragent". Чтобы подсчитать, сколько раз определенные ОС произошли в строках user-agent, я использовал следующий запрос 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, когда, затем, строка user-agent ищется для определенных элементов и переводится на понятное имя ОС. Внешний запрос затем группирует эти недавно созданные имена ОС и подсчитывает частоту каждой ОС, выводя что-то вроде этого:
+---------------+------+
| 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)
эти данные затем могут быть сброшены прямо в библиотеку, такую как диаграмма.js, который автоматически сделает круговую диаграмму из частоты данные. Или вы можете вычислить проценты сами относительно суммы всех частот.
если у вас также есть столбец даты или метки времени рядом с каждой строкой пользовательского агента, вы можете добавить предложение WHERE, например, только показать статистику ОС и браузеров, используемых за последние шесть месяцев.