Страница 1 из 2
MySQL: скорость выполнения запросов
Добавлено: 2008-06-24 11:35:56
lodErunnEr
Считаю трафик. Для этого есть база (пока примерно 50 метров.. в дальнейшем будет сильно расти) 2е таблицы (в одной 2а столбца, в другой 10). На данный момент около 300 тысяч записей.
Дык вот... вот такой вот запрос:
Код: Выделить всё
SELECT accesslog.clientadr, ip.descript, sum(accesslog.bytes) AS traf
FROM accesslog LEFT JOIN ip ON accesslog.clientadr = ip.adr
GROUP BY accesslog.clientadr
ORDER BY traf desc;
выполняется где-то 5 секунд.
При этом загрузка процессора не возрастает больше 20%.
Беспокоит довольно большое время выполнения запроса.
Нормально ли это?
Re: MySQL: скорость выполнения запросов
Добавлено: 2008-06-24 11:37:36
LMik
Индексы в таблице имеются? Правильно ли расставлены?
Re: MySQL: скорость выполнения запросов
Добавлено: 2008-06-24 11:46:18
lodErunnEr
угу. насчет правильно расставлены не знаю
делал так:
Код: Выделить всё
create table accesslog(
id int(4) not null auto_increment,
....
....
primary key(id)
);
Re: MySQL: скорость выполнения запросов
Добавлено: 2008-06-24 12:06:54
zg
EXPLAIN в студию
Re: MySQL: скорость выполнения запросов
Добавлено: 2008-06-24 12:40:47
lodErunnEr
zg писал(а):EXPLAIN в студию
Код: Выделить всё
mysql> explain select accesslog.clientadr, ip.descript, sum(accesslog.bytes) as traf from accesslog left join ip on accesslog.clientadr = ip.adr group by accesslog.clientadr order by traf desc;
+----+-------------+-----------+------+---------------+------+---------+------+--------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+------+---------------+------+---------+------+--------+---------------------------------+
| 1 | SIMPLE | accesslog | ALL | NULL | NULL | NULL | NULL | 322432 | Using temporary; Using filesort |
| 1 | SIMPLE | ip | ALL | NULL | NULL | NULL | NULL | 1 | |
+----+-------------+-----------+------+---------------+------+---------+------+--------+---------------------------------+
2 rows in set (0.00 sec)
Re: MySQL: скорость выполнения запросов
Добавлено: 2008-06-24 12:47:08
zg
тебе надо добавить индекс на accesslog.clientadr и первичный ключ на ip.adr . У тебя щас индексов вообще нет, а связь один ко многим.
Re: MySQL: скорость выполнения запросов
Добавлено: 2008-06-24 12:54:18
lodErunnEr
zg писал(а):тебе надо добавить индекс на accesslog.clientadr и первичный ключ на ip.adr . У тебя щас индексов вообще нет, а связь один ко многим.
Спасибо огромное.. только я нислова не понял
Хотя бы ткни что читать по теме..
Что значит "индекс на accesslog.clientadr и первичный ключ на ip.adr"?
Разве primary key(id) не достаточно?
Re: MySQL: скорость выполнения запросов
Добавлено: 2008-06-24 13:00:13
zg
lodErunnEr писал(а):Спасибо огромное.. только я нислова не понял
Хотя бы ткни что читать по теме..
http://downloads.mysql.com/docs/refman-4.0-ru.html.zip начинаешь от тега <html> и заканчиваешь </html>
lodErunnEr писал(а):Что значит "индекс на accesslog.clientadr и первичный ключ на ip.adr"?
Разве primary key(id) не достаточно?
достаточно, осталось добавить индекс на accesslog.clientadr
Код: Выделить всё
ALTER TABLE `accesslog` ADD INDEX ( `clientadr` )
Re: MySQL: скорость выполнения запросов
Добавлено: 2008-06-24 13:06:13
zg
lodErunnEr писал(а):Считаю трафик
и ничего не тормозит вся база в три раза больше, это самая большая таблица.
Код: Выделить всё
--
-- Структура таблицы `billing_traffic_ips`
--
CREATE TABLE billing_traffic_ips (
udate date NOT NULL default '0000-00-00',
ip_dest int(1) unsigned NOT NULL default '0',
net_id tinyint(1) unsigned NOT NULL default '0',
bytes bigint(1) unsigned NOT NULL default '0',
KEY udate (udate)
) ENGINE=MyISAM DEFAULT CHARSET=koi8r COMMENT='Траффик по ip';
вот и все дела ))
Re: MySQL: скорость выполнения запросов
Добавлено: 2008-06-24 13:07:24
lodErunnEr
Сделал. Кажись добавил
Код: Выделить всё
describe accesslog;
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| id | int(4) | NO | PRI | NULL | auto_increment |
| time | varchar(255) | NO | | | |
| duration | varchar(255) | NO | | | |
| clientadr | varchar(15) | NO | MUL | | |
| resultcode | varchar(255) | NO | | | |
| bytes | int(4) | YES | | NULL | |
| method | varchar(255) | NO | | | |
| site | varchar(255) | NO | | | |
| url | text | YES | | NULL | |
| username | varchar(255) | YES | | NULL | |
+------------+--------------+------+-----+---------+----------------+
- скорость не изменилась =(
Код: Выделить всё
explain select accesslog.clientadr, ip.descript, sum(accesslog.bytes) as traf from accesslog left join ip on accesslog.clientadr = ip.adr group by accesslog.clientadr order by traf desc;
+----+-------------+-----------+------+---------------+------+---------+------+--------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+------+---------------+------+---------+------+--------+---------------------------------+
| 1 | SIMPLE | accesslog | ALL | NULL | NULL | NULL | NULL | 322432 | Using temporary; Using filesort |
| 1 | SIMPLE | ip | ALL | NULL | NULL | NULL | NULL | 1 | |
+----+-------------+-----------+------+---------------+------+---------+------+--------+---------------------------------+
Re: MySQL: скорость выполнения запросов
Добавлено: 2008-06-24 14:45:26
zg
lodErunnEr писал(а):Сделал. Кажись добавил
не, надо так
lodErunnEr писал(а):скорость не изменилась =(
вот когда possible_keys и key будут заполнены, тогда изменится, кстати приведи пару строчек из таблицы accesslog
Re: MySQL: скорость выполнения запросов
Добавлено: 2008-06-24 15:00:53
dikens3
Re: MySQL: скорость выполнения запросов
Добавлено: 2008-06-24 15:10:51
lodErunnEr
zg писал(а):скорость не изменилась =(
вот когда possible_keys и key будут заполнены, тогда изменится, кстати приведи пару строчек из таблицы accesslog[/quote]
Код: Выделить всё
mysql> select * from accesslog limit 2;
+--------+----------------+----------+----------------+--------------+-------+--------+--------------+--------------------------------+----------+
| id | time | duration | clientadr | resultcode | bytes | method | site | url | username |
+--------+----------------+----------+----------------+--------------+-------+--------+--------------+--------------------------------+----------+
| 934658 | 1213715357.902 | 817 | 192.168.242.34 | TCP_MISS/200 | 47440 | GET | cars.avto.ru | http://cars.avto.ru/search/? | - |
| 934659 | 1213715358.064 | 339 | 192.168.242.34 | TCP_MISS/200 | 15222 | GET | bs.yandex.ru | http://bs.yandex.ru/code/1157? | - |
+--------+----------------+----------+----------------+--------------+-------+--------+--------------+--------------------------------+----------+
2 rows in set (0.02 sec)
Re: MySQL: скорость выполнения запросов
Добавлено: 2008-06-24 15:43:34
zg
в своей практике столкнулся с тем, что пихать логи в базу нет никакого смысла, обрабатывать их проще на С и awk, при этом скорость в разы больше, а в базу пихать только отчётную статистику, которая занимает копейки
Re: MySQL: скорость выполнения запросов
Добавлено: 2008-06-24 15:54:38
lodErunnEr
zg писал(а):в своей практике столкнулся с тем, что пихать логи в базу нет никакого смысла, обрабатывать их проще на С и awk, при этом скорость в разы больше, а в базу пихать только отчётную статистику, которая занимает копейки
эхх... т.е. ничем мне не помочь ?
Re: MySQL: скорость выполнения запросов
Добавлено: 2008-06-24 16:00:19
zg
lodErunnEr писал(а):zg писал(а):в своей практике столкнулся с тем, что пихать логи в базу нет никакого смысла, обрабатывать их проще на С и awk, при этом скорость в разы больше, а в базу пихать только отчётную статистику, которая занимает копейки
эхх... т.е. ничем мне не помочь ?
я тебе для чего ссылку кидал?
и выложи show create table
Re: MySQL: скорость выполнения запросов
Добавлено: 2008-06-24 16:19:51
lodErunnEr
Код: Выделить всё
accesslog | CREATE TABLE `accesslog` (
`id` int(4) NOT NULL auto_increment,
`time` varchar(255) default NULL,
`duration` varchar(255) default NULL,
`clientadr` varchar(15) default NULL,
`resultcode` varchar(255) default NULL,
`bytes` int(4) default NULL,
`method` varchar(255) default NULL,
`site` varchar(255) default NULL,
`url` text,
`username` varchar(255) default NULL,
PRIMARY KEY (`id`),
KEY `clientadr` (`clientadr`)
) ENGINE=MyISAM AUTO_INCREMENT=345928 DEFAULT CHARSET=latin1
Re: MySQL: скорость выполнения запросов
Добавлено: 2008-06-24 17:42:25
zg
Код: Выделить всё
explain select
accesslog.clientadr,
sum(accesslog.bytes) as traf
from
accesslog
group by
accesslog.clientadr
order by
traf desc;
я думаю, результат будет тот же... индексы не используются, если количсетво записей в них больше определённого процента, поскольку будет быстрее прочесать всю таблицу, это уже пройдено. Тебе нужно скоратить количество записей в индексе, нужно проиндексировать только часть ip-адреса
Код: Выделить всё
ALTER TABLE `accesslog` DROP INDEX `clientadr` ,
ADD INDEX `clientadr` ( `clientadr` ( 4 ) )
это позволит сократить количество записей в индексе, после этого выложи предыдущий запрос
Re: MySQL: скорость выполнения запросов
Добавлено: 2008-06-24 19:32:36
lodErunnEr
Код: Выделить всё
mysql> explain select accesslog.clientadr, ip.descript, sum(accesslog.bytes) as traf from accesslog left join ip on accesslog.clientadr = ip.adr group by accesslog.clientadr order by traf desc;
+----+-------------+-----------+------+---------------+------+---------+------+--------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+------+---------------+------+---------+------+--------+---------------------------------+
| 1 | SIMPLE | accesslog | ALL | NULL | NULL | NULL | NULL | 357518 | Using temporary; Using filesort |
| 1 | SIMPLE | ip | ALL | NULL | NULL | NULL | NULL | 1 | |
+----+-------------+-----------+------+---------------+------+---------+------+--------+---------------------------------+
Код: Выделить всё
mysql> show create table accesslog;
.....
accesslog | CREATE TABLE `accesslog` (
`id` int(4) NOT NULL auto_increment,
`time` varchar(255) default NULL,
`duration` varchar(255) default NULL,
`clientadr` varchar(15) default NULL,
`resultcode` varchar(255) default NULL,
`bytes` int(4) default NULL,
`method` varchar(255) default NULL,
`site` varchar(255) default NULL,
`url` text,
`username` varchar(255) default NULL,
PRIMARY KEY (`id`),
KEY `clientadr` (`clientadr`(4))
) ENGINE=MyISAM AUTO_INCREMENT=357519 DEFAULT CHARSET=latin1 |
Код: Выделить всё
mysql> select accesslog.clientadr, ip.descript, sum(accesslog.bytes) as traf from accesslog left join ip on accesslog.clientadr = ip.adr group by accesslog.clientadr order by traf desc;
+-----------------+----------+-----------+
| clientadr | descript | traf |
+-----------------+----------+-----------+
| 192.168.242.197 | NULL | 468522648 |
| 192.168.242.13 | NULL | 253419872 |
| 192.168.242.53 | NULL | 220497743 |
| 192.168.242.34 | NULL | 215650269 |
| 192.168.242.64 | NULL | 210015783 |
| 192.168.242.73 | NULL | 205025671 |
| 192.168.242.16 | NULL | 188901301 |
| 192.168.242.55 | NULL | 177384665 |
| 192.168.242.35 | NULL | 148118629 |
| 192.168.242.71 | NULL | 130003238 |
| 192.168.242.43 | NULL | 122762579 |
| 192.168.242.208 | NULL | 94173834 |
| 192.168.242.105 | NULL | 90276998 |
| 192.168.242.82 | NULL | 58765293 |
| 192.168.242.135 | NULL | 57748097 |
| 192.168.242.157 | NULL | 53682158 |
| 192.168.242.141 | user01 | 50552397 |
| 192.168.242.75 | NULL | 47247918 |
| 192.168.242.76 | NULL | 35265138 |
| 192.168.242.93 | NULL | 30843712 |
| 192.168.242.21 | NULL | 24335505 |
| 192.168.242.41 | NULL | 23471645 |
| 192.168.242.88 | NULL | 23201228 |
| 192.168.242.32 | NULL | 22929654 |
| 192.168.242.65 | NULL | 16545952 |
| 192.168.242.46 | NULL | 14672151 |
| 192.168.242.18 | NULL | 11877211 |
| 192.168.242.19 | NULL | 9843094 |
| 192.168.242.211 | NULL | 8973557 |
| 192.168.242.30 | NULL | 4379815 |
| 192.168.242.200 | NULL | 1952373 |
| 192.168.242.79 | NULL | 1049814 |
| 192.168.242.58 | NULL | 475212 |
| 192.168.242.201 | NULL | 339680 |
| 192.168.242.66 | NULL | 37465 |
+-----------------+----------+-----------+
35 rows in set (5.05 sec)
=(
эх.. пошел я читать документацию ..
Re: MySQL: скорость выполнения запросов
Добавлено: 2008-06-24 19:56:22
dikens3
На это поле попробуй index добавить. Вообще поэкперементируй, не всегда всё работает так как хочешь.
Re: MySQL: скорость выполнения запросов
Добавлено: 2008-06-24 21:11:57
zg
dikens3 писал(а):На это поле попробуй index добавить. Вообще поэкперементируй, не всегда всё работает так как хочешь.
это поле sum(), на него индекс нельзя добавить, только если сделать временную таблицу
Re: MySQL: скорость выполнения запросов
Добавлено: 2008-06-24 22:01:13
dikens3
Млять, я парю. Невнимательность.
Re: MySQL: скорость выполнения запросов
Добавлено: 2008-06-25 6:01:34
zg
lodErunnEr писал(а):=(
как вариант можешь либо базу выложить, либо доступ открыть, либо сделать копию базы и на неё дать доступ, я гляну чё и как, потом отпишусь.
Re: MySQL: скорость выполнения запросов
Добавлено: 2008-06-25 8:34:15
lodErunnEr
zg писал(а):lodErunnEr писал(а):=(
как вариант можешь либо базу выложить, либо доступ открыть, либо сделать копию базы и на неё дать доступ, я гляну чё и как, потом отпишусь.
отправил ЛС.
Re: MySQL: скорость выполнения запросов
Добавлено: 2008-06-25 9:35:16
zg
lodErunnEr писал(а):отправил ЛС.
Код: Выделить всё
SQL-запрос #1:
--------------
CREATE TABLE `log2` (
`udate` DATE NOT NULL ,
`ip` INT( 1 ) UNSIGNED NOT NULL ,
`bytes` BIGINT( 1 ) UNSIGNED NOT NULL ,
PRIMARY KEY ( `udate` , `ip` )
) TYPE = MYISAM CHARACTER SET cp1251 COLLATE cp1251_general_ci COMMENT = 'Суммарный трафик пользователей';
SQL-запрос #2:
--------------
INSERT INTO `log2`
SELECT from_unixtime( `time` , '%Y-%m-%d' ) `udate` , inet_aton( `clientadr` ) ip, sum( `bytes` ) `bytes`
FROM accesslog
GROUP BY `udate` , `ip`
Отчётный запрос по сотрудникам
(Показывает записи 0 - 29 (146 всего, Запрос занял 0.0941 сек))
--------------
SELECT
lg.udate,
INET_NTOA(lg.ip) ip,
lg.bytes,
`ip`.descript
FROM
`log2` lg
LEFT JOIN `ip`
ON
lg.`ip` = INET_ATON(`ip`.`adr`)
WHERE
`udate` BETWEEN "2008-06-01" AND "2008-06-31"
---------------
udate ip bytes descript
2008-06-17 192.168.242.34 7794283 NULL
2008-06-17 192.168.242.200 1931790 NULL
2008-06-17 192.168.242.211 672064 NULL
2008-06-18 192.168.242.13 64731682 NULL
2008-06-18 192.168.242.16 42679375 NULL
2008-06-18 192.168.242.18 2375509 NULL
2008-06-18 192.168.242.19 2166456 NULL
2008-06-18 192.168.242.21 14700619 NULL
2008-06-18 192.168.242.30 159556 NULL
2008-06-18 192.168.242.34 97672539 NULL
2008-06-18 192.168.242.35 33631446 test user 3
2008-06-18 192.168.242.41 22958417 NULL
2008-06-18 192.168.242.43 21321293 NULL
2008-06-18 192.168.242.53 26118536 NULL
2008-06-18 192.168.242.55 57986412 NULL
2008-06-18 192.168.242.58 471890 NULL
2008-06-18 192.168.242.64 43282787 NULL
2008-06-18 192.168.242.65 2967533 NULL
2008-06-18 192.168.242.71 300448 NULL
2008-06-18 192.168.242.73 112823136 test user 2
.....
Итого
Код: Выделить всё
Было:
-------------
Данные 46,936 KB
Индекс 7,877 KB
Всего 54,813 KB
Формат динамический
Сравнение latin1_swedish_ci
Ряды 357,518
Длина ряда ? 134
Размер ряда ? 157 Bytes
Стало:
-------------
Данные 2,336 Bytes
Индекс 4,096 Bytes
Всего 6,432 Bytes
Формат фиксированный
Сравнение cp1251_general_ci
Ряды 146
Длина ряда ? 16
Всю остальную информацию нужно брать из логов, а в базе хранить только отчётную информацию.
У меня в статистике по логам бегает греп или авк, отчёты берутся из базы, в итоге скорость достпуа к любой информации составляет доли секунды.