高效的MySQL查询/模式,用于存储来自并行进程的信息

时间:2012-08-28 15:06:27

标签: mysql sql

问题

我有处理平面文件记录的多个并行进程。每个文件对应于电信系统中的给定接口(通过系统的消息被赋予 32位全局唯一标识符,并且在多个接口上可以存在给定消息的记录)。处理每个文件的一个进程

让我们调用接口:A,B和C.消息字符串可以根据它所写的接口而有所不同。我应该创建一个表来存储有关通过系统的每条消息的信息。因此,此表应包含(以及其他字段): id,message_on_A,message_on_B,message_on_C。我想避免使用相同ID的重复条目。

我尝试的是以下内容:

  1. 将id设置为PRIMARY KEY并使用INSERT ON DUPLICATE KEY UPDATE命令为每个进程设置相应的消息字段
  2. 将id分解为多个部分并将这些部分用作复合主键;其余的与1相同。
  3. 存储所有记录,然后使用第二个查询提取每个id的所有信息(使用GROUP BY ID,max(message_on_A),max(message_on_B),max(message_on_C))。没有为此方法定义主键。
  4. 这些方法都不够快。我正在寻找一种解决方案,可以为100万个ID实现大约30秒的运行时间(因此考虑3个接口的300万条记录)。

    第一种和第二种方法在MyISAM表上大约400秒完成了这项工作。我也尝试过InnoDB,但速度要慢得多。

    目前我正在考虑给方法3另一个镜头,但我需要找到一个更快的查询(GROUP BY和max()查询持续超过20分钟才终止它)

    问题: 任何人都可以为这个问题提出更好的架构吗?还有一个更好的查询?

2 个答案:

答案 0 :(得分:2)

我正在考虑修改第三种方法。将数据存储在三个单独的表中,GUId作为每个表中的主键。这应该使插入尽可能快地发生。处理此级别的重复项。

请尝试以下方法,而不是分组:

select A.id,
       A.message as A_message,
       (select B.message from B where B.id = A.id limit 1) as B_message,
       (select C.message from C where C.id = A.id limit 1) as C_message
from A

如果这样可行,那么唯一的问题是当消息缺少A组件时。我认为还有一种方法可以解决这个问题。问题是这是否能实现您的绩效目标。

答案 1 :(得分:1)

innodb有很多配置参数。我相信这个存储引擎在并发环境中会表现得更好。 mysql的默认设置不适合现代硬件 - 所以可能从tuning开始并重新运行基准测试。