1

问题

我有多个处理平面文件记录的并行进程。每个文件对应于电信系统中的给定接口(通过系统的消息被赋予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))。没有为此方法定义主键。

这些方法都不够快。我正在寻找一种解决方案,它可以为 100 万个 id 实现大约 30 秒的运行时间(考虑到 3 个接口,因此有 300 万条记录)。

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

目前我正在考虑再次尝试方法 3,但我需要找到一个更快的查询(GROUP BY 和 max() 查询在我终止之前持续了 20 多分钟)

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

4

2 回答 2

2

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

而不是 group by,请尝试以下操作:

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 组件时。我认为也有办法解决这个问题。问题是这是否能实现您的绩效目标。

于 2012-08-28T15:31:16.010 回答
1

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

于 2012-08-28T15:18:55.037 回答