Оптимизация MySQL для большой таблицы myisam
OS=centos 6.7 [Dedicated server]
memory=15G
cpu=Intel(R) Xeon(R) CPU E5-2403
mysql= V 5.1.73
Вот таблица MyISAM и содержит около 5 миллионов строк данных. Через каждые 5-6 минут вставляются данные примерно для 3000 пользователей (например, скорость загрузки и загрузки, статус сеанса и т. д.).
информация таблицы: опишите "radacct"
мой.cnf
из mysql медленный журнал запросов один из запросов, который занимает больше всего времени ниже
Query_time: 7.941773 Lock_time: 0.155912 Rows_sent: 1 Rows_examined: 5377
use freeradius;
SET timestamp=1461582118;
SELECT sum(acctinputoctets) as upload,
sum(acctoutputoctets) as download
FROM radacct a
INNER JOIN (SELECT acctuniqueid, MIN( radacctid ) radacctid
FROM radacct
WHERE username='batman215'
and acctstarttime between '2016-02-03 12:10:47'
and '2016-04-25 16:46:01'
GROUP BY acctuniqueid) b
ON a.acctuniqueid = b.acctuniqueid
AND a.radacctid = b.radacctid;
объяснить результат запроса
когда есть много пользователей, которые пытаются увидеть их потребления пропускной способности сервер не может выполнить запросы из-за высокой нагрузки и ИО. Есть ли что-то, что я могу сделать для дальнейшей оптимизации базы данных ?
индексы из таблицы "radacct"
объяснить запрос без использования G
спасибо
2 ответов
давайте разберемся с этим, начиная с вашего внутреннего запроса, который:
SELECT acctuniqueid,
MIN( radacctid ) radacctid
FROM radacct
WHERE username='batman215'
and acctstarttime between '2016-02-03 12:10:47'
and '2016-04-25 16:46:01'
GROUP BY acctuniqueid
вы ищете матч равенства на username и матч диапазона на acctstarttime. Затем вы используете acctuniqueid для группировки и вытягивания экстремального значения (MIN()) от radacctid.
поэтому, чтобы ускорить этот подзапрос, вам нужен следующий составной индекс.
(username, acctstarttime, acctuniqueid, radacctid)
как это работает? Подумайте об индексе (это индексы BTREE) как отсортированном списке значений в он.
- обработчик запросов произвольно обращается к списку -- fast, O (log (n)) -- чтобы найти первую запись, соответствующую
usernameи нижний конец вашего
WHERE username='batman215'
and acctstarttime between ...
просит INDEX(username, acctstarttime) в таком порядке.
ON a.acctuniqueid = b.acctuniqueid
AND a.radacctid = b.radacctid;
просит INDEX(acctuniqueid, radacctid) (в любом порядке) (или индекс покрытия Олли).
"каждые 5-6 минут вставляются данные примерно для 3000 пользователей" просит InnoDB вместо MyISAM. MyISAM делает блокировки таблиц, тем самым "вставка" вмешивается в другие запросы. советы по преобразованию.





