[英]Optimize query?
我的查詢花了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 |
+----+-------------+-------+--------+---------------+---------+---------+------+---------+---------------------------------+
因此,通常來看您的查詢,我們發現表event
a
正在檢查8,177,074行。 這可能是速度緩慢的“根源”,因此我們想看看如何使用索引來減少搜索空間。
event
a
的主要條件是
n.net=inet_ntoa(a.ip_src)
這里的問題是,我們需要在a.ip_src的每一行上執行計算(inet_ntoa),因此除了掃描整個表外別無選擇。 可能更好的解決方案是反轉比較並確保索引a.ip_src。
a.ip_src=inet_aton(n.net)
這只會更好,如果我們在匹配的行數更少n
比我們是在a
。 如果不是這種情況,則應認真考慮將此函數的結果緩存在表中並在該表上創建索引。
最后,我猜測timestamp列是在event
a
,在這種情況下,索引可能會有助於排序和分組,盡管可能沒有幫助。 您可以嘗試在(ip_src,timestamp)上使用multi_column索引
在WHERE/JOIN
子句中使用的列上引入至少索引的做法。 我使用了至少,因為在許多情況下應該嘗試使用PRIMARY/FOREIGN KEY
關系。 因此,如果某事物已經是主/外鍵,則無需對其進行進一步索引。
可以通過以下查詢引入INDEX來簡單地改進上述查詢:
ALTER TABLE events ADD INDEX idx_ev_ipsrc (ip_src);
這里idx_ev_ipsrc
=索引鍵的名稱,而ip_src
是要索引的列。
甚至進一步增強:
使用以下查詢在網絡表上引入多列索引:
ALTER TABLE network ADD INDEX idx_net_fsi_net (fsi,net);
上面的結果將導致行數更少。
注意:上面的查詢是針對MySql的,可以輕松地為其他數據庫量身定制。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.