新しいプロジェクトに使用するデータベース システムを評価しようとしています。
現時点では、目前のタスクについて MySQL と MongoDB を比較しています。
350 の数値フィールドで 500 万件の記録があり、このデータを使用して、グラフのプロットにさまざまな粒度レベルを提供する必要があります。
データを MongoDB と Mysql に送り込み、Mysql で 10/th、100/th、1000/th の粒度の中間テーブルをいくつか生成しました。次に、アプリケーションは、現在のタスクに最適な正しいテーブルを選択し、そこでデータをクエリします。
この手法を使用すると、十分な速さでデータを取得できます (< 100 ms)。私が使用するSQLクエリは次のとおりです。
SELECT from_unixtime(CAST(FLOOR(MIN(STAMP/1000)) AS SIGNED INTEGER)),
MIN(RING),MIN(STATE),CAST(FLOOR(MIN(STAMP)) as SIGNED INTEGER),AVG(w21030401)
FROM project1 GROUP BY FLOOR((stamp - 1181589892000)/60000);
中間テーブルの作成には、同じクエリを使用します。唯一の違いは、350 個の wXXXXXX フィールドがあることです。
INSERT INTO project1_10 (TTIME,RING,STATE,STAMP,w21030401,.........)
SELECT from_unixtime(CAST(FLOOR(MIN(STAMP/1000)) AS SIGNED INTEGER)),
MIN(RING),MIN(STATE),CAST(FLOOR(MIN(STAMP)) as SIGNED INTEGER),AVG(w21030401),.......
FROM project1 GROUP BY FLOOR((stamp - 1181589892000)/60000);
次に、MongoDB で同じことをしようとしました。すべてのデータを MongoDB に投入し、次の形式で 480 万のドキュメントを取得しました。
{ "_id" : ObjectId("50040b3f0cf2872a8d3af90d"), "TTIME" :
ISODate("2008-11-30T06:40:07Z"), "STAMP" : NumberLong("1228027207000"),
"STATE" : 2531, "RING" : 1, "w13010096" : 34.991, "w13010097" : 1.432,
"w23010001" : 292, "w18030180" : 84, "w18030380" : 95, "w21030002" : 51.113,
"w21030005" : 60.321, "w21030004" : 274.662, "w21030008" : 149.629,
"w21030009" : 126.565, "w21030010" : 576.296, ........... }
次に、次の mapReduce を使用して中間ドキュメントを生成しようとしました。
keylist = [ 'w21030401', 'w13011114', .... ];
m = function (){
var result = {};
result['STAMP'] = this['STAMP'];
result['RING'] = this['RING'];
result['TTIME'] = this['TTIME'];
result['STATE'] = this['STATE'];
for(var key in keylist){
if(key in this) {
result[key] = this[key];
result['cnt_' + key] = 1;
}
}
var zone = Math.floor((this['STAMP'] - 1171004118000) / 1000000);
emit( zone , result );
};
r = function (name, values){
var result = {};
result['STAMP'] = values[0]['STAMP'];
result['RING'] = values[0]['RING'];
result['TTIME'] = values[0]['TTIME'];
result['STATE'] = values[0]['STATE'];
for(var key in keylist) {
result[key] = 0;
result['cnt_' + key] = 0;
}
for ( var i=0; i<values.length; i++ ) {
if(values[i]['STAMP'] < result['STAMP']) {
result['STAMP'] = values[i]['STAMP'];
result['TTIME'] = values[i]['TTIME'];
}
if(values[i]['RING'] < result['RING']) {
result['RING'] = values[i]['RING'];
}
if(values[i]['STATE'] < result['STATE']) {
result['STATE'] = values[i]['STATE'];
}
for(var key in keylist) {
if(key in values[i]) {
result[key] += values[i][key];
result['cnt_' + key] += values[i]['cnt_' + key];
}
}
}
return result;
};
f = function(who, val){
var result = {};
result['STAMP'] = val['STAMP'];
result['RING'] = val['RING'];
result['TTIME'] = val['TTIME'];
result['STATE'] = val['STATE'];
for(var key in keylist) {
if(key in val) {
result[key] = val[key]/val['cnt_'+key];
}
}
return result;
};
db.project1.mapReduce( m, r, { finalize : f, scope: { keylist: keylist }, out : {replace : 'project1_100'} , jsMode : false });
MySQL は中間テーブルの作成に 210 秒を使用し、MongoDB は約 4 時間を使用しました。
私の質問は次のとおりです。MongoDB は私の問題に適していませんか、MongoDB には MySQL よりも大きなハードウェアが必要ですか、それとも MapReduce で何か間違ったことをしましたか?
ありがとう
ピーター