【发布时间】:2011-08-30 17:23:34
【问题描述】:
我有一个项目,我必须改进它的性能。我有一个由巨大的 CSV 文件(1 亿行)构建的大型 Mysql 数据库。插入时间不是问题,但请求的响应时间非常重要,有时带有 2 个连接的查询需要大约 20 小时...
为了减少响应时间,我尝试将我的数据库迁移到 Cassandra,但没有成功:我的数据模型不适用于 Cassandra 概念。然后我想尝试另一种提高性能的方法:并行虚拟文件系统。而是在 Mysql 数据库中插入数据并发送然后发送查询,我尝试使用多线程读取整个 csv 文件并进行计算。但结果并不好:仅 1 000 000 行 2m20s。
目前,我的计算非常简单:在 C++ 中使用 MPI-IO API,我只计算 2 列中不同对值的数量。为了执行该计算,我使用了一个哈希图,其中每个键都是来自 csv 文件的一对值。最后,我返回哈希图大小。 这里有一个小代码:
MPI::Init(argc,argv);
cout << " INFO init done" << endl;
int myrank = MPI::COMM_WORLD.Get_rank();
int numprocs = MPI::COMM_WORLD.Get_size();
get_filename(path_name, myrank);
cout << " INFO open file : " << path_name << endl;
MPI::File thefile = MPI::File::Open(MPI::COMM_WORLD, path_name.c_str(),
MPI::MODE_RDONLY,
MPI::INFO_NULL);
MPI::Offset offset = 101;
MPI::Offset limit = thefile.Get_size();
cout << " INFO go computing" << endl;
do {
thefile.Read_at(offset, buf, bufsize, MPI_CHAR, status);
temp.assign(buf);
Tokenize(temp,tokens,"\n");
line.assign(tokens.at(0));
tokens.clear();
Tokenize(line,tokens,"\t");
nidt_count(tokens);
tokens.clear();
offset += (line.size() + 1);
}while(offset < limit);
count = status.Get_count(MPI_INT);
cout << "process " << myrank << " reads " << nidt_hash.size() << " nidt" << endl;
我在一台 4 核、8GB 内存的服务器上工作。我的数据在我的服务器上安装在 NFS 或 Samba 中的 NAS 上。我可以添加 2 或 3 台服务器进行处理,但目前我只是在一台服务器上尝试了一个小文件(100 万行)来衡量性能。
最后我的问题是:
- 对于我的问题,考虑更改为 PVFS 类型是一种好方法吗?我想说我将处理更复杂的查询,例如:选择具有特定日期(范围小时)的所有行,以及来自特定列的特定对值。
- 您知道其他可以帮助我改进 csv 文件处理的方法吗?我正在考虑使用 Hadoop、Pytables 或 FasterCSV。
这是我由 2 个 csv 文件组成的数据样本:
最大的(1亿行)组成如下:
ID DATE NUM_1 NUM_2 NB_UNITE TYPUNIT CODE_1 CODE_2
0 2007-05-13 15:37:48 33671624244 33698802900 547 s 0 17
0 2007-05-13 15:52:22 33671624244 33672211799 5 s 0 17
....
第二个更简单更小(90 000),它就像一本字典,从code_1 和code_2 我得到一个名为 CODEVAL 的值:
CODE_1 CODE_2 CODEVAL
0 17 VS
0 34 SS
如您所料,通常我为每个文件创建 2 个表,一个典型的查询是:
Select CODEVAL, hour(date) AS HEURE, COUNT(*) AS NBSMSSOR
From Tables_1 Join CODEVAL using(CODE_1,CODE_2)
Where CODEVAL='SS'
对不起,我不知道如何制作数组。
这是我由 2 个 csv 文件组成的数据样本:
-
最大的(1亿行)组成如下:
ID DATE NUM_1 NUM_2 NB_UNITE TYPUNIT CODE_1 CODE_2
0 2007-05-13 15:37:48 33671624244 33698802900 547 秒 0 17
0 2007-05-13 15:52:22 33671624244 33672211799 5 秒 0 17 .... -
第二个更简单更小(90 000),它就像一个字典,从 code_1 和 code_2 我得到一个名为 CODEVAL 的值:
CODE_1 CODE_2 CODEVAL
0 17 VS
0 34 不锈钢
如您所料,通常我为每个文件创建 2 个表,一个典型的查询是:
- 选择 CODEVAL,小时(日期)作为 HEURE,计数(*)作为 NBSMSSOR 来自 Tables_1 使用 (CODE_1,CODE_2) 加入 CODEVAL 其中 CODEVAL='SS'
对不起,我不知道如何制作数组。
【问题讨论】:
-
有没有试过分析调优MySql:forge.mysql.com/wiki/Top10SQLPerformanceTips
-
如果您使用的不是最新版本的 MySQL,请考虑升级,并阅读 @ChrisWue 的链接,这是很棒的东西。
-
我会更关心您的数据布局以及您如何访问它们。您能否粘贴一个包含 10 行的示例以及您使用的最常见查询?
-
感谢您的帮助,您可以在下面看到我用 CSV 文件编写的数据示例。我也写了一个简单的查询。
-
一亿行听起来不像是一个大数据库,即使按照 MySQL 标准。
标签: c++ multithreading performance csv mpi