MySQL用大表表现不佳

时间:2018-02-12 14:44:08

标签: mysql database transactions query-optimization

我有一个监控表,其中包含大约200多台服务器的监控数据。 每个服务器每天每分钟向表中添加3条数据记录。

我为客户提供了6个月的历史报告数据,您可以想象这个表格非常大。

我目前的问题是在这个表上运行SELECT查询需要一个年龄。 我理解为什么;这是执行SELECT时所经历的大量行,但我试图通过添加时间查找来显着减少结果集...

SELECT * FROM `host_monitoring_data` 
WHERE parent_id = 47 AND timestamp > (NOW() - INTERVAL 5 MINUTE);

...但是在数据返回给我之前我还在看很长时间。

我习惯使用相当小的桌子,这是迄今为止我用过的最大的桌子,所以我不熟悉如何克服这类问题。

任何帮助都非常有用。

我的表结构当前是id,parent_id,timestamp,type,U,A,T

U,A,T是使用/可用/总计,类型告诉我我们正在使用哪种可测量的,Timestamp就是这样,parent_id是数据所属的父主机的id,id是有问题记录的自动递增ID。

当我在进行查找时,我基本上试图获取最近的20行,其中parent_id = x或者其他什么,所以我只是...

SELECT u,a,t from host_monitoring_data 
WHERE parent_id=X AND timestamp > (NOW() - INTERVAL 5 MINUTE) 
ORDER BY timestamp DESC LIMIT 20

编辑1 - 包括EXPLAIN的结果:

EXPLAIN SELECT * FROM `host_monitoring_data` 
WHERE parent_id=36 AND timestamp > (NOW() - INTERVAL 5 MINUTE) 
ORDER BY timestamp DESC LIMIT 20

id select_type table                type possible_keys key key_len ref rows Extra
1  SIMPLE      host_monitoring_data ALL  NULL          NULL NULL   NUL 2865454
Using where; Using filesort

2 个答案:

答案 0 :(得分:2)

根据你的EXPLAIN报告,我看到它说"输入:ALL"这意味着它会扫描每个查询的所有行(整个表)。

您需要一个索引来帮助它扫描更少的行。

parent_id=X的第一个条件是明显的选择。您应该创建一个以parent_id开头的索引。

timestamp >= ...上的另一个条件可能是最好的第二选择。您的索引应包含timestamp作为第二列。

您可以这样创建此索引:

ALTER TABLE host_monitoring_data ADD INDEX (parent_id, timestamp);

您可能会喜欢我的演示文稿this以及我提供的视频:How to Design Indexes, Really

P.S。:当您提出有关查询优化的问题时,请运行SHOW CREATE TABLE <tablename>并将其输出包含在您的问题中。这向我们展示了您的列,数据类型,当前索引和约束。别让我们猜!帮助我们帮助您!

答案 1 :(得分:1)

三个好的提示:

  1. EXPLAIN(正如其他人所说),会告诉你你在做什么,并提示做得更好。

  2. 避免使用“*”,而是选择所需的字段。

  3. 使用过程分析来了解您需要的最推荐的变量类型(如果需要,可以更改它们)。

  4. https://dev.mysql.com/doc/refman/5.7/en/procedure-analyse.html

    我也尽量避免使用“order by”。