[英]Optimize query?
My query took 28.39 seconds to run. 我的查询花了28.39秒才能运行。 How can I optimize it?
我该如何优化?
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 |
+----+-------------+-------+--------+---------------+---------+---------+------+---------+---------------------------------+
So generally looking at your query, we find that table event
a
is examining 8,177,074 rows. 因此,通常来看您的查询,我们发现表
event
a
正在检查8,177,074行。 That is likely the "root" of the slowness, so we want to look at how to reduce the search space using indexes. 这可能是速度缓慢的“根源”,因此我们想看看如何使用索引来减少搜索空间。
The main condition on event
a
is event
a
的主要条件是
n.net=inet_ntoa(a.ip_src)
The problem here is that we need to perform a calculation (inet_ntoa) on every row of a.ip_src, so there is no alternative but to scan the entire table. 这里的问题是,我们需要在a.ip_src的每一行上执行计算(inet_ntoa),因此除了扫描整个表外别无选择。 A potentially better solution would be to invert the comparison and ensure that a.ip_src is indexed.
可能更好的解决方案是反转比较并确保索引a.ip_src。
a.ip_src=inet_aton(n.net)
This will only be better if we are matching less rows in n
than we are in a
. 这只会更好,如果我们在匹配的行数更少
n
比我们是在a
。 If that is not the case, you should seriously consider caching the result of this function in the table and creating an index on that. 如果不是这种情况,则应认真考虑将此函数的结果缓存在表中并在该表上创建索引。
Lastly I am guessing the timestamp column is in event
a
, in which case an index will potentially help with ordering and grouping though may not. 最后,我猜测timestamp列是在
event
a
,在这种情况下,索引可能会有助于排序和分组,尽管可能没有帮助。 You could try a multi_column index on (ip_src,timestamp) 您可以尝试在(ip_src,timestamp)上使用multi_column索引
Make it a practice to introduce at-least index on columns which can be used in WHERE/JOIN
clauses. 在
WHERE/JOIN
子句中使用的列上引入至少索引的做法。 I've used the at-least because in many cases one should try to use PRIMARY/FOREIGN KEY
relations. 我使用了至少,因为在许多情况下应该尝试使用
PRIMARY/FOREIGN KEY
关系。 So if something is already a primary/foriegn key there is no need to index it further. 因此,如果某事物已经是主/外键,则无需对其进行进一步索引。
The above query can be simply improved by introducing the INDEX through the following query: 可以通过以下查询引入INDEX来简单地改进上述查询:
ALTER TABLE events ADD INDEX idx_ev_ipsrc (ip_src);
Here idx_ev_ipsrc
= Name of the index key, and ip_src
is the column to be indexed. 这里
idx_ev_ipsrc
=索引键的名称,而ip_src
是要索引的列。
Even further enhancement: 甚至进一步增强:
Introduce multi-colum index on network table using following query: 使用以下查询在网络表上引入多列索引:
ALTER TABLE network ADD INDEX idx_net_fsi_net (fsi,net);
The above will result in even low number of rows. 上面的结果将导致行数更少。
Note: The above queries are for MySql and can be tailored for other DBs easily. 注意:上面的查询是针对MySql的,可以轻松地为其他数据库量身定制。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.