Golthana Опубликовано: 22 июня, 2016 Опубликовано: 22 июня, 2016 Извините, если в в той теме. Вопрос по оптимизации работы mysql. Есть таблица, в которой хранится netflow. Любой запрос выполняется 10 мин. Как диагностировать проблему?
KaYot Опубликовано: 22 июня, 2016 Опубликовано: 22 июня, 2016 http://mysqltuner.com/ Качаете скрипт, запускаете, он вам все подробно расскажет.
Golthana Опубликовано: 22 июня, 2016 Автор Опубликовано: 22 июня, 2016 Да. Запускал, выполнил рекомендации. Все равно выполнение запроса = 10 минутам. При том, что select COUNT(*) from 'table_name'; Делается быстро.
alsdfg Опубликовано: 22 июня, 2016 Опубликовано: 22 июня, 2016 Да. Запускал, выполнил рекомендации. Все равно выполнение запроса = 10 минутам. При том, что select COUNT(*) from 'table_name'; Делается быстро. Смотрите http://dev.mysql.com/doc/refman/5.7/en/explain.html Также смотрите чтобы были индексы на поля по которым происходит выборка в запросе.
Golthana Опубликовано: 22 июня, 2016 Автор Опубликовано: 22 июня, 2016 mysql> EXPLAIN SELECT * FROM raw;+----+-------------+-------+------+---------------+------+---------+------+-----------+-------+| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |+----+-------------+-------+------+---------------+------+---------+------+-----------+-------+| 1 | SIMPLE | raw | ALL | NULL | NULL | NULL | NULL | 820510737 | NULL |+----+-------------+-------+------+---------------+------+---------+------+-----------+-------+1 row in set (0.01 sec)
bodidron Опубликовано: 22 июня, 2016 Опубликовано: 22 июня, 2016 теорию БД курите( НФ не даром придумали
Golthana Опубликовано: 22 июня, 2016 Автор Опубликовано: 22 июня, 2016 Вот структура: mysql> show create table raw;+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Table | Create Table |+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| raw | CREATE TABLE `raw` ( `unix_secs` int(11) unsigned NOT NULL DEFAULT '0', `unix_nsecs` int(11) unsigned NOT NULL DEFAULT '0', `sysuptime` int(11) unsigned NOT NULL DEFAULT '0', `exaddr` varchar(15) NOT NULL DEFAULT '0', `dpkts` int(11) unsigned NOT NULL DEFAULT '0', `doctets` int(11) unsigned NOT NULL DEFAULT '0', `srcaddr` varchar(15) NOT NULL DEFAULT '0', `dstaddr` varchar(15) NOT NULL DEFAULT '0', `srcport` smallint(5) unsigned NOT NULL DEFAULT '0', `dstport` smallint(5) unsigned NOT NULL DEFAULT '0', `prot` tinyint(3) unsigned NOT NULL DEFAULT '0') ENGINE=MyISAM DEFAULT CHARSET=latin1 |+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+1 row in set (0.00 sec)
bos Опубликовано: 22 июня, 2016 Опубликовано: 22 июня, 2016 я конечно не силен, в БД, но мне кажется, что если вы проведете партиционирование таблицы, и перепишите запросы чтобы они использовали все прелести партиционирования, то будет значительно легче. использование innodb так же предпочтительнее, разработчики говорят что myisam безнадежно устарел и в след 7м релизе будет выпилен. (по заявлениям некоторых людей innodb показывает более лучшие результаты и в olap oltp )
KaYot Опубликовано: 22 июня, 2016 Опубликовано: 22 июня, 2016 Первым делом нужно поменять движок таблицы на InnoDB, и задать для mysql здоровенный innodb_pool. Сейчас у вас запросы вероятно вообще не кешируются и каждый раз выполняются с вычиткой всей таблицы с диска.
NiTr0 Опубликовано: 22 июня, 2016 Опубликовано: 22 июня, 2016 Вот структура 1) как уже сказали - InnoDB вместо окаменелости MyISAM 2) индексы где? без индексов - мускул тупо сравнивает каждую из 820 млн строк с критериями where...
Golthana Опубликовано: 22 июня, 2016 Автор Опубликовано: 22 июня, 2016 индексы где? Их на каждый столбец прописывать?
Golthana Опубликовано: 22 июня, 2016 Автор Опубликовано: 22 июня, 2016 SELECT FROM_UNIXTIME(unix_secs), srcaddr, (SUM(doctets)/1024)/1024 as 'doctets' FROM raw WHERE srcaddr = '".$ip."' AND DATE_FORMAT(FROM_UNIXTIME(unix_secs), '%Y-%m-%d') between '".$startdate."' AND '".$enddate."' GROUP BY DATE_FORMAT(FROM_UNIXTIME(unix_secs), '%Y-%m-%d') Вот весь запрос
KaYot Опубликовано: 22 июня, 2016 Опубликовано: 22 июня, 2016 Индексами должны быть поля используемые в where. У вас это unix_secs и srcaddr. Добавьте, это сразу даст многократный буст к скорости обработки.
Golthana Опубликовано: 22 июня, 2016 Автор Опубликовано: 22 июня, 2016 (изменено) CREATE INDEX ip ON raw(srcaddr); и CREATE INDEX date ON raw(unix_secs) ТАК? А запрос поменяется от этого? Движок таблицы уже уже сменил Изменено 22 июня, 2016 пользователем Golthana
KaYot Опубликовано: 22 июня, 2016 Опубликовано: 22 июня, 2016 Запрос не поменяется, индексы лишь упрощают движку поиск в таблице. Теоретически 1 индекс на базе 2ух полей в вашем случае(с миллионами записей) будет еще эффективнее, но тут жена-архитектор БД сказала "хз, нужно тестить" Добавьте индексы, дайте базе большой кэш innodb и будет все космически.
NiTr0 Опубликовано: 22 июня, 2016 Опубликовано: 22 июня, 2016 DATE_FORMAT(FROM_UNIXTIME(unix_secs), '%Y-%m-%d') between '".$startdate."' AND '".$enddate." эта херня принципиально неиндексируемая. уж не в абиллсе ли такой бред подсмотрели? делайте нормальный запрос (да-да, startdate и enddate в unixtime, а не вырывание гланд через анус) и делайте индекс по полям, используемым в выборке.
Golthana Опубликовано: 22 июня, 2016 Автор Опубликовано: 22 июня, 2016 делайте нормальный запрос Например? уж не в абиллсе ли такой бред подсмотрели? Нет. В какой-то статье прочитал. Поскольку в mysql несилен, то не могу оценить правильность введенного запроса
foreverok Опубликовано: 22 июня, 2016 Опубликовано: 22 июня, 2016 Индексы, движки - это конечно все возможно и даст небольшой прирост. Судя по самому запросу и размеру БД, проблема в том, что создается временная таблица на диске (диски наверное не ssd?), причем не маленькая. Посмотрите размер временной таблицы которая создается при выполнении запроса, возможно удастся засунуть её в tmpfs.
Golthana Опубликовано: 22 июня, 2016 Автор Опубликовано: 22 июня, 2016 диски наверное не ssd?) Нет Посмотрите размер временной таблицы которая создается при выполнении запроса, возможно удастся засунуть её в tmpfs. А ссылку на документацию по этому поводу можно? Или в двух словах?
KaYot Опубликовано: 22 июня, 2016 Опубликовано: 22 июня, 2016 (изменено) А с какой стати автоматически создаваться временной таблице? Изменено 22 июня, 2016 пользователем KaYot
Golthana Опубликовано: 22 июня, 2016 Автор Опубликовано: 22 июня, 2016 (изменено) Создаю два индекса. Процесс задумался, видимо время надо) Потом сравню результат. SELECT FROM_UNIXTIME(unix_secs), srcaddr, (SUM(doctets)/1024)/1024 as 'doctets' FROM raw WHERE srcaddr = '".$ip."' AND FROM_UNIXTIME(unix_secs) between '".$startdate."' AND '".$enddate."' GROUP BY FROM_UNIXTIME(unix_secs); Такой запрос имелся ввиду? Изменено 22 июня, 2016 пользователем Golthana
Golthana Опубликовано: 22 июня, 2016 Автор Опубликовано: 22 июня, 2016 | Table | Create Table |+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| raw | CREATE TABLE `raw` ( `unix_secs` int(11) unsigned NOT NULL DEFAULT '0', `unix_nsecs` int(11) unsigned NOT NULL DEFAULT '0', `sysuptime` int(11) unsigned NOT NULL DEFAULT '0', `exaddr` varchar(15) NOT NULL DEFAULT '0', `dpkts` int(11) unsigned NOT NULL DEFAULT '0', `doctets` int(11) unsigned NOT NULL DEFAULT '0', `srcaddr` varchar(15) NOT NULL DEFAULT '0', `dstaddr` varchar(15) NOT NULL DEFAULT '0', `srcport` smallint(5) unsigned NOT NULL DEFAULT '0', `dstport` smallint(5) unsigned NOT NULL DEFAULT '0', `prot` tinyint(3) unsigned NOT NULL DEFAULT '0') ENGINE=InnoDB DEFAULT CHARSET=latin1 |
Melanxolik Опубликовано: 22 июня, 2016 Опубликовано: 22 июня, 2016 Я бы ip загонял в ntoa. Unixsec генерирует кучу неповторных значений что заставляет сканировать таблицу до поиска соответствий. Ради интереса. Если сперва найти диапазон времени и потом ip?
Рекомендованные сообщения
Создайте аккаунт или войдите в него для комментирования
Вы должны быть пользователем, чтобы оставить комментарий
Создать аккаунт
Зарегистрируйтесь для получения аккаунта. Это просто!
Зарегистрировать аккаунтВойти
Уже зарегистрированы? Войдите здесь.
Войти сейчас