【发布时间】:2020-12-19 11:24:02
【问题描述】:
我有一个数据库表,其中包含设备及其状态 ..up 或 down。 当设备更改状态时,该表会从设备监控应用程序更新。
CREATE TABLE device_status(
time TIMESTAMP(6) NOT NULL,
device_name VARCHAR(10) NOT NULL,
type ENUM('up', 'down') NOT NULL,
device_status_id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY);
INSERT INTO device_status VALUES
('2020-07-01 09:00:00.000001','device1','down',NULL),
('2020-07-01 09:00:05.000001','device2','down',NULL),
('2020-07-01 10:00:00.000001','device3','down',NULL),
('2020-07-01 10:00:05.000001','device1','up',NULL),
('2020-07-01 10:00:08.000001','device1','down',NULL),
('2020-07-01 11:00:00.000001','device2','down',NULL),
('2020-07-01 11:00:05.000001','device1','up',NULL);
mysql> select * from device_status;
+----------------------------+-------------+------+------------------+
| time | device_name | type | device_status_id |
+----------------------------+-------------+------+------------------+
| 2020-07-01 09:00:00.000001 | device1 | down | 1 |
| 2020-07-01 09:00:05.000001 | device2 | down | 2 |
| 2020-07-01 10:00:00.000001 | device3 | down | 3 |
| 2020-07-01 10:00:05.000001 | device1 | up | 4 |
| 2020-07-01 10:00:06.000001 | device2 | up | 5 |
| 2020-07-01 10:00:08.000001 | device1 | down | 6 |
| 2020-07-01 11:00:00.000001 | device2 | down | 7 |
| 2020-07-01 11:00:05.000001 | device1 | up | 8 |
+----------------------------+-------------+------+------------------+
8 rows in set (0.00 sec)
我想创建一个显示当前停机设备的查询。输出 对于上表应显示如下内容:
+----------------------------+-------------+------+------------------+
| time | device_name | type | device_status_id |
+----------------------------+-------------+------+------------------+
| 2020-07-01 11:00:00.000001 | device2 | down | 7 |
| 2020-07-01 10:00:00.000001 | device3 | down | 3 |
+----------------------------+-------------+------+------------------+
2 rows in set (0.00 sec)
我有 700 台设备,每天向表中添加大约 5k 条记录。 非常感谢任何帮助!
好的,所以这个查询确实产生了所需的结果,但是随着表的增长,它需要很长时间..当前表有大约 50k 行,大约需要 5 分钟 :-(
mysql> select t1.*
-> from device_status t1
-> left outer join device_status t2
-> on (t1.device_name = t2.device_name and t1.time < t2.time)
-> where (t2.device_name is null and t1.type = 'down')
-> order by device_name;
+----------------------------+-------------+------+------------------+
| time | device_name | type | device_status_id |
+----------------------------+-------------+------+------------------+
| 2020-07-01 11:00:00.000001 | device2 | down | 7 |
| 2020-07-01 10:00:00.000001 | device3 | down | 3 |
+----------------------------+-------------+------+------------------+
2 rows in set (0.00 sec)
我已按照建议为列添加索引:
mysql> describe device_status;
+------------------+-------------------+------+-----+----------------------+--------------------------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+-------------------+------+-----+----------------------+--------------------------------+
| time | timestamp(6) | NO | MUL | CURRENT_TIMESTAMP(6) | on update CURRENT_TIMESTAMP(6) |
| device_name | varchar(10) | NO | MUL | NULL | |
| type | enum('up','down') | NO | MUL | NULL | |
| device_status_id | int(10) unsigned | NO | PRI | NULL | auto_increment |
+------------------+-------------------+------+-----+----------------------+--------------------------------+
4 rows in set (0.02 sec)
我还增加了 12k 条记录:
mysql> SELECT COUNT(*) FROM device_status;
+----------+
| COUNT(*) |
+----------+
| 12002 |
+----------+
1 row in set (0.01 sec)
现在如果我运行我的原始查询:
mysql> select t1.*
-> from device_status t1
-> left outer join device_status t2
-> on (t1.device_name = t2.device_name and t1.time < t2.time)
-> where (t2.device_name is null and t1.type = 'down')
-> order by device_name;
+----------------------------+-------------+------+------------------+
| time | device_name | type | device_status_id |
+----------------------------+-------------+------+------------------+
| 2020-08-31 15:48:58.597929 | device1 | down | 12001 |
| 2020-08-31 15:48:58.677924 | device2 | down | 12002 |
+----------------------------+-------------+------+------------------+
2 rows in set (23.56 sec)
所以我想我在这里做错了..非常感谢所有帮助!
【问题讨论】:
-
尝试在您的时间戳列上使用
order by。
标签: mysql