简体   繁体   English

优化查询?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM