Как управлять огромной базой данных (MySQL) - PullRequest
1 голос
/ 06 ноября 2011

Я написал платформу статистики / отслеживания для мониторинга активности моих сайтов. Для каждого пользователя в таблице создается запись с некоторой соответствующей информацией: IP, Ref, код страны GeoLocate и т. Д.

База данных содержит результаты более 7 мм и имеет размер около 4 ГБ.

Теперь у меня есть скрипт, который должен выполнять SUM-запросы для получения количества показов, кликов и т. Д. За определенный промежуток времени ($ from_date & $ to_date).

$query = "SELECT COUNT(ip) as tot, sum(clicked=0) as a0, sum(clicked=1) as a1, sum(converted=0) as a2, sum(converted=1) as a3 FROM tf_data WHERE cid='".$cid."' and stamp between ".$from_date." and ".$to_date." "; 

Один этот запрос загружается НАВСЕГДА, даже если я на приличной машине VPS. У меня есть несколько других запросов, подобных этому, на моей странице сводки, что приводит к частому тайм-ауту скрипта (REQUEST TIMEOUT: этот запрос обрабатывается слишком долго, он задержан сервером. Если время не истекло, обратитесь к администратору этого веб-сайта, чтобы увеличить «Время ожидания подключения».)

Что мне делать? Как я могу справиться с этим огромным количеством данных? Должен ли я создать отдельную таблицу и запустить задание cron, чтобы вставить / обновить число показов, число кликов ...?

Как обычно это делается?

Спасибо как всегда!

РЕДАКТИРОВАТЬ: СТРУКТУРА СТОЛОВ:

CREATE TABLE `tf_data` (
`click_id` int(11) NOT NULL AUTO_INCREMENT,
`ip` varchar(225) NOT NULL,
`agent` text NOT NULL,
`referer` text NOT NULL,
`stamp` text NOT NULL,
`country` varchar(30) NOT NULL,
`src` text NOT NULL,
`adspot` varchar(250) NOT NULL,
`cid` text NOT NULL,
`adid` text NOT NULL,
`lp` varchar(250) NOT NULL,
`offer` int(11) NOT NULL,
`clicked` int(11) NOT NULL,
`converted` int(11) NOT NULL,
`converted2` int(11) NOT NULL,
`price` varchar(255) NOT NULL,
PRIMARY KEY (`click_id`),
UNIQUE KEY `ip` (`ip`)
) ENGINE=MyISAM AUTO_INCREMENT=9599999 DEFAULT CHARSET=latin1

Ответы [ 3 ]

4 голосов
/ 06 ноября 2011

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

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

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

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

2 голосов
/ 06 ноября 2011

7 миллионов строк не так уж много. Сколько строк возвращает нормальное предложение WHERE?

Всякий раз, когда у вас есть проблемы с производительностью запроса, смотрите на план выполнения запроса .

Спросите себя: «У меня есть правильные типы данных?» Как указал Мэтью Уотсон, в этой таблице нет типа данных метки времени (DATETIME). В этом случае использование DATETIME вместо TEXT, вероятно, уменьшит размер вашей базы данных примерно на 10 байт на строку. (Я предполагаю, что «штамп» может быть ДАТА вместо DATETIME. Меньше сбережений, но все же сбережений, и нет преобразований для сравнения дат.)

Спросите себя: "Могу ли я улучшить индексацию?" Вам нужны индексы для "cid" и "stamp" как минимум.

Задайте себе вопрос: "Могу ли я уменьшить количество столбцов в базовой таблице или в запросе?" (Сочетание «преобразованный» и «преобразованный2» является подозрительным.)

Задайте себе вопрос: «Могу ли я уменьшить количество строк?»

После того, как вы все это сделали, рассмотрите разбиение .

После разбиения (или, может быть, до разбиения) рассмотрите таблицы OLAP для суммирования.

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

В качестве быстрого решения я бы предложил автономные вычисления + разбиение таблиц + индекс HASH для cid и индекс BTree для печати. Долгосрочное решение будет использовать решение для хранилища данных NoSQL, такое как Cassandra и, возможно, Hadoop + Pig для расчета и передачи данных в Cassandra.

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