![]()  | 
		
Задавайте вопросы, мы ответим
Вы не зашли.
У меня есть таблица статистики типа ЛОГ. В него складывается вся статистика ротатора баннеров с сайтах компании.
Дошло до того, что записей в базе стало 3 000 000 
 И Даже обычный COUNT() перестал летать как раньше.
Вот таблица лога
CREATE TABLE `log` (
  `id` int(19) NOT NULL auto_increment,
  `id_account` int(11) NOT NULL default '0',
  `id_banner` int(11) NOT NULL default '0',
  `date` int(11) NOT NULL default '0',
  `action` varchar(5) NOT NULL,
  `ip` varchar(16) NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `date` (`date`),
  KEY `id_banner` (`id_banner`),
  KEY `ip` (`ip`),
  KEY `action` (`action`),
  KEY `idaccount_idbanner` (`id_account`,`id_banner`,`date`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251;
Подскажите как ещё можно оптимизировать эту часть.
А я быстро сделал CRON который запускается каждый час и вносит в другую таблицу уже более быструю для выбора статистику.
Вот таблица для CRON
CREATE TABLE `stat_cron` (
  `views` int(11) NOT NULL default '0',
  `u_views` int(11) NOT NULL default '0',
  `clicks` int(11) NOT NULL default '0',
  `u_clicks` int(11) NOT NULL default '0',
  `accountid` int(11) NOT NULL default '0',
  `bannerid` smallint(6) NOT NULL default '0',
  `date` date NOT NULL default '0000-00-00',
  `hour` tinyint(2) NOT NULL default '0',
  PRIMARY KEY  (`accountid`,`bannerid`,`date`,`hour`),
  KEY `accountid_day` (`accountid`,`date`),
  KEY `bannerid_day` (`accountid`,`bannerid`,`date`),
  KEY `views` (`views`),
  KEY `u_views` (`u_views`),
  KEY `clicks` (`clicks`),
  KEY `u_clicks` (`u_clicks`),
  KEY `hour` (`hour`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251;
А из этой таблицы как мне кажеться будут данные быстро выводиться
SUM(views) AS views
FROM stat_cron
WHERE accountid = 5
AND date = сегодня
Помогите пожалуйста. Ото сервак скоро вешаться будет ![]()
Неактивен

Вы не указали, какие именно запросы к первой таблице наиболее часто происходят. Посмотрите SHOW FULL PROCESSLIST, когда сервер замедляется и включите журнал медленных запросов. Оптимизируется именно приложение, а не просто таблица. 
Хранение преобработанной статистики - правильный путь, Вы можете обновлять вторую таблицу по триггеру BEFORE INSERT в первой таблице, а не по cron, например. 
Кстати, почему в первой таблице не было ключа   KEY `accountid_day` (`accountid`,`date`)?
Неактивен
Вот я переработал структуру таблиц.
#1
CREATE TABLE `log_acc` (
  `id` int(19) NOT NULL auto_increment,
  `id_account` int(11) NOT NULL default '0',
  `id_banner` int(11) NOT NULL default '0',
  `date` int(11) NOT NULL default '0',
  `action` varchar(5) NOT NULL,
  `ip` varchar(16) NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `id_banner` (`id_banner`),
  KEY `ip` (`ip`),
  KEY `action` (`action`),
  KEY `date_idaccount_ip` (`date`,`id_account`,`ip`),
  KEY `id_account` (`id_account`)
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=cp1251 AUTO_INCREMENT=3 ;
# 2
CREATE TABLE `stat_acc_cron` (
  `views` int(11) NOT NULL default '0',
  `u_views` int(11) NOT NULL default '0',
  `clicks` int(11) NOT NULL default '0',
  `u_clicks` int(11) NOT NULL default '0',
  `accountid` int(11) NOT NULL default '0',
  `bannerid` smallint(6) NOT NULL default '0',
  `date` date NOT NULL default '0000-00-00',
  `hour` tinyint(2) NOT NULL default '0',
  PRIMARY KEY  (`date`,`hour`,`accountid`,`bannerid`),
  KEY `views` (`views`),
  KEY `u_views` (`u_views`),
  KEY `clicks` (`clicks`),
  KEY `u_clicks` (`u_clicks`),
  KEY `hour` (`hour`),
  KEY `bannerid_date` (`bannerid`,`date`),
  KEY `accountid_date` (`accountid`,`date`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251;
И теперь вот такие запросы чаще всего идут в MySQL
# в первую таблицу
INSERT INTO log_acc (id_account,id_banner,date,action,ip)
VALUES (
'21',211,'3212321','click','127.0.0.1'
)
SELECT COUNT(*) AS count
FROM log_acc
WHERE date = '3212321'
AND accountid = '21'
AND ip = '127.0.0.1'
# во вторую таблицу
SELECT COUNT(*) AS count
FROM stat_acc_cron
WHERE date = '2008-04-12'
AND hour = '13'
AND accountid = '21'
SELECT COUNT(*) AS count
FROM stat_acc_cron
WHERE date = '2008-04-12'
AND hour = '13'
AND accountid = '21'
AND bannerid = '211'
И вот такой вот
SELECT SUM(views) AS count
FROM stat_acc_cron
WHERE date = '2008-04-12'
Иногда к этому запросу добавляется AND accountid = '21'
Вот. МОжет так будет лучше для совета по оптимизации.
Неактивен

Сделайте EXPLAIN SELECT COUNT(*) AS count
FROM log_acc
WHERE date = '3212321'
AND accountid = '21'
AND ip = '127.0.0.1'
Увидите, что он полностью ключ   KEY `date_idaccount_ip` (`date`,`id_account`,`ip`),
Посмторите SHOW STATUS LIKE 'key%' как используется key_buffer - он значительно ускоряет запросы, работающие по ключу.
Другие приведенные запросы также должны использовать ключи, проверьте это через EXPLAIN.
Что именно тормозит сейчас? Где узкое место? (см также С чего начинать оптимизацию MySQL )
Неактивен
rgbeast написал:
Увидите, что он полностью ключ KEY `date_idaccount_ip` (`date`,`id_account`,`ip`),
Так это же хорошо?
P.S. Тут статью я уже читал.
Неактивен

Так это же хорошо?
Да, это хорошо. Поэтому я и спросил какие именно запросы работают медленно. Вставка не должна тормозить, запросы по ключу быстрые по своей природе - здесь как раз важно помещается ли ключ в кэш. Так как ключей много, то все в кэш могут не поместиться, поэтому рекомендую создать именованный кэш и хранить в нем наиболее востребованные 1-2 ключа, см. http://sqlinfo.ru/articles/info/3.html
P.S. статья про оптимизацию будет продолжена, точнее по каждому отдельному пункту предполагается написать отдельный материал
Неактивен