2015-03-27 2 views
0

Мой запрос занял 28,39 секунды. Как я могу его оптимизировать?Оптимизировать запрос?

explain SELECT distinct UNIX_TIMESTAMP(timestamp)*1000 as timestamp,count(a.sig_name) as counter from event a,network n where n.fsi='pays' and n.net=inet_ntoa(a.ip_src) group by date(timestamp) order by timestamp asc; 
+----+-------------+-------+--------+---------------+---------+---------+--- ---+---------+---------------------------------+ 
| id | select_type | table | type | possible_keys | key  | key_len | ref | rows | Extra       | 
+----+-------------+-------+--------+---------------+---------+---------+------+---------+---------------------------------+ 
| 1 | SIMPLE  | a  | ALL | NULL   | NULL | NULL | NULL | 8177074 | Using temporary; Using filesort | 
| 1 | SIMPLE  | n  | eq_ref | PRIMARY,fsi | PRIMARY | 77  | func |  1 | Using where      | 
+----+-------------+-------+--------+---------------+---------+---------+------+---------+---------------------------------+ 
+0

Вы должны опубликовать свой план запроса, но на первый взгляд ваше соединение кажется, что оно будет довольно интенсивным. 'n.fsi = 'pays' и n.net = inet_ntoa (a.ip_src)'. Как по сравнению с строкой, так и с возможностью запуска функции в каждой строке, вероятно, будет основной частью вашего времени обработки. – paqogomez

ответ

2

Так вообще, глядя на ваш запрос, мы находим, что таблица eventa рассматривает 8,177,074 строк. Вероятно, это «корень» медленности, поэтому мы хотим посмотреть, как уменьшить пространство поиска с помощью индексов.

Главное условие на eventa является

n.net=inet_ntoa(a.ip_src) 

Проблема здесь состоит в том, что нам нужно выполнить расчет (inet_ntoa) на каждой строке a.ip_src, так что нет никакой альтернативы, кроме как сканировать всю Таблица. Потенциально лучшим решением было бы инвертировать сравнение и обеспечить индексацию a.ip_src.

a.ip_src=inet_aton(n.net) 

Это будет только лучше, если мы сопоставления меньше строк в n, чем мы в a. Если это не так, вам следует серьезно подумать о кешировании результата этой функции в таблице и создании индекса.

Наконец-то я догадываюсь, что столбец timestamp находится в eventa, и в этом случае индекс потенциально может помочь с упорядочением и группировкой, хотя может и не быть. Вы можете попробовать индекс multi_column на (ip_src, timestamp)

+1

Спасибо Очень Очень Очень ... все, что я сейчас в порядке – jarjar

0

Сделать практикой введение индекса по крайней мере на столбцы, который может использоваться в статьях WHERE/JOIN. Я использовал, по крайней мере, потому, что во многих случаях следует попытаться использовать отношения PRIMARY/FOREIGN KEY. Поэтому, если что-то уже является основным/foriegn-ключом, нет необходимости индексировать его дальше.

Этот запрос может быть просто улучшена путем введения INDEX через следующий запрос:

ALTER TABLE events ADD INDEX idx_ev_ipsrc (ip_src);

Здесь idx_ev_ipsrc = Имя ключа индекса, и ip_src это столбец для индексирования.

Даже дальнейшее повышение:

Ввести индекс мульти-Colum на сетевой таблице, используя следующий запрос:

ALTER TABLE network ADD INDEX idx_net_fsi_net (fsi,net);

выше приведет к еще низкое число строк.

Примечание. Вышеупомянутые запросы предназначены для MySql и могут быть легко адаптированы для других БД.

Смежные вопросы