Оптимизация 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 делает блокировки таблиц, тем самым "вставка" вмешивается в другие запросы. советы по преобразованию.