优化的mysql表模式,用于读写数据

时间:2017-08-30 10:22:09

标签: mysql database performance optimization schema

我正在开发一个项目,该项目需要将来自多个跟踪设备的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;

2 个答案:

答案 0 :(得分:2)

正如单独讨论中所建议的那样:

  • 将所有表合并到一个主表
  • 在查询的Timestamp部分使用索引列(where)以大大提高速度
  • 增加innodb_buffer_pool_size以减少磁盘IO时间

答案 1 :(得分:1)

“设备”在移动吗?如果没有,请不要在表格中包含lat / lng。同样任何其他不变的价值观。

有一张桌子。

请按此顺序拥有PRIMARY KEY(device_id, timestamp)。请注意,这会将插入内容分成表格的单独部分。

不要(没有充分理由)重复timestampdate中的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硬盘?