我正在开发一个项目,该项目需要将来自多个跟踪设备的mysql中的数据存储到服务器中。数据间隔为10秒。
目前我们存储数据的方式如下:
每个设备都有一个表({Device_Number} _info),其中Unix时间戳为主键。 (因此,如果我们有10,000个设备,我们最终会有10,000个表。这样做是为了防止锁定,因为我们每10秒插入一次表。)
每隔10秒将数据插入相应的表中,然后再访问。
这种方法的问题是,如果我们必须为每个设备获得一行 - 我们必须遍历所有10,000个表并执行查询。我们尝试了所有可能的方法来优化查询并向表中添加索引,但没有任何作用。循环遍历所有表并执行查询需要时间。我们的目标是获得<10s的行。我觉得有些东西可以使用mysql优化技术来改进。
我们尝试了什么:
我们创建了所有10,000个表的单个视图(采用联合)。然后查询视图。这也不起作用。这需要2分钟以上。
有关如何为优化的读写设计架构的任何建议?
这是{device_number} _info table:
的架构{device_number}_info:
device_number int(11) NOT NULL,
Date date NOT NULL,
Time time NOT NULL,
Timestamp int(10) unsigned DEFAULT NULL,
Speed float NOT NULL,
Latitude double NOT NULL,
Longitude double NOT NULL,
...
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
答案 0 :(得分:2)
正如单独讨论中所建议的那样:
Timestamp
部分使用索引列(where
)以大大提高速度innodb_buffer_pool_size
以减少磁盘IO时间答案 1 :(得分:1)
“设备”在移动吗?如果没有,请不要在表格中包含lat / lng。同样任何其他不变的价值观。
有一张桌子。
请按此顺序拥有PRIMARY KEY(device_id, timestamp)
。请注意,这会将插入内容分成表格的单独部分。
不要(没有充分理由)重复timestamp
和date
中的time
。在大多数情况下,您可以动态转换。
DOUBLE
对于lat / lng来说是过度杀伤力。有关较小的选项,请参阅this。
缩小表格大小可以提高性能。
每秒插入1000行时,将它们分批并使用单个LOAD DATA
或单个多行INSERT
进行批处理。它需要一些时间,但它应该远低于10秒(下降限制),除了“冷”系统。
device_number
可以是MEDIUMINT UNSIGNED
(3个字节而不是4个;限制为16M - 1.6亿卢比)。
如果您要在指定时间内为所有设备提取数据,则需要辅助INDEX(timestamp)
。
请记住,更多索引意味着INSERTs
更慢,因此请提供您认为需要的所有索引以及它们的设计查询。我们应该讨论它们。
您保存数据多长时间了?听起来每年300亿行?如果你要清除,那么DELETE
就成了一个严重的问题。我们可以讨论一下。
多少内存?硬盘还是SSD硬盘?