2017-09-22 9 views
0

実際には、SQliteを使用していくつかの属性を持つファイルのリストをいくつか保存していますが、リレーショナルデータは1つのファイルに複数のデータしかないので、リレーショナルデータベースやnosql DBは有効です。 現在の問題は、検索の速度です。ノードを使用してdbを埋め込み、プロジェクトフォルダにファイルを格納する必要があります。実際にノードsqlite3を使用していますが、yerterdayにはより良いsqlite3モジュールをテストしました。類似。高速の検索速度を持つノード埋め込みデータベース

私のテーブルの構造は、このようなものです:arroundの300.000行の

╔════╦══════════════╦══════════╦════════════════╦═════════╦═══════════════╦══════════════════╗ 
║ id ║  hash  ║ name ║ description ║ date ║  tags  ║ languages  ║ 
╠════╬══════════════╬══════════╣════════════════╣═════════╣═══════════════╣══════════════════╣ 
║INT ║  TEXT  ║ TEXT ║  TEXT  ║ NUMBER ║  JSON  ║  JSON  ║ 
║ 2 ║ b2b22b2b2bb2 ║ two test ║ lorem ipsum b ║ 1233123 ║ ["d","e","f"] ║ ["ko","en","tk"] ║ 
║ 3 ║ asdasdasdsad ║ 333 test ║ lorem ipsum c ║ 1233123 ║ ["a","d","c"] ║ ["es","de","fr"] ║ 
║ 4 ║ 4s342s423424 ║ 444 test ║ lorem ipsum d ║ 1233123 ║ ["a","b","g"] ║ ["es","pt","fr"] ║ 
╚════╩══════════════╩══════════╩════════════════╩═════════╩═══════════════╩══════════════════╝ 

結果は以下のとおりです。

Select * from files WHERE name LIKE "%string%":300msの

select * from files WHERE (tags LIKE '"music"' OR tags LIKE '"banana"') AND (languages LIKE '"esp"' OR languages LIKE '"ger"'):400msの

select id from files:130msの(としてみてください"count(id)をcounter FROM files"として選択すると、それが遅くなり結果がカウントされます30ms vs 150ms)

結果は悪くないが、ここでは1回の検索操作であり、私のプログラムでは複数のユーザーが同時に検索できるため、検索時間が不安定になる。 (10クライアント、応答あたり4秒〜) 500Gb SSD(550R/450W)を使用してCore i7 4820Kでテストを実行している場合、RAID0がクエリ時間を大幅に増やす

私はindexxを作成しようとしていますすべての検索列は、このプロジェクトの挿入はocassionalですので、私は挿入速度についてはあまり気にしませんが、名前、タグまたは言語フィールドにインデックスを置くので、奇妙です(arround 50msのみ、しかし増加

私が探している代替案は、極端な検索速度とDBロックなしのDBを必要とします(私はDBが2M行に成長できると思っていますが)莫大な量を消費することはありませんメモリの量は、リレーショナルであるかどうかについて気にしないでください。

EDIT:イムは、多くの多くのテストを作り、ここに私の結果は次のとおりです。

ノードlmdb作成速度はmemcacheのと仕事のように、4秒で100.000挿入をarroung、insanelly速く、データを読み取るためには、働いていますたくさん良い、しかしので私はJSONで与えられたデータを変換して、「検索」のロジックを作成する必要があり、キーと値のデータベース、およびこの減少された結果、ここでのサンプルコードは、次のとおりです。

const crypto = require('crypto') 
const lmdb = require('node-lmdb') 

const env = new lmdb.Env() 

env.open({ 
    path: __dirname + "/mydata", 
    mapSize: 2*1024*1024*1024, // maximum database size 
    maxDbs: 3 
}) 

var dbi = env.openDbi({ 
    name: "myPrettyDatabase", 
    create: true // will create if database did not exist 
}) 

// Begin transaction 
var txn = env.beginTxn() 

let t0 = new Date().getTime() 


// Create cursor 
let cursor = new lmdb.Cursor(txn, dbi) 
let counter = 0 
let find = 0 

for (var found = cursor.goToFirst(); found !== null; found = 
cursor.goToNext()) { 
    cursor.getCurrentString(function(key, data) { 

     let js 
     try { 
      js = JSON.parse(data) 
      counter++ 
     } catch (e) { js = null } 

     if (js && String(js.name).indexOf('Lorem') !== -1) { 
      find++ 
     } 
    }) 
} 

console.log('counter: ' + counter) 
console.log('find: ' + find) 

// Close cursor 
cursor.close(); 


let t1 = new Date().getTime() 
console.log('time: ' + (t1-t0)) 


// Commit transaction 
txn.commit() 

dbi.close() 

結果は次のとおりです。

$ node index.js カウンター:215548 検索:113073 時間:1516

リスト速度が

I(何か間違ったことやIM)arroundの200msのが、JSON変換とsqliteのスピードの下で遅くlitle "検索" の論理でありますTingodbと他の実験を行い、それが埋め込みDBであるが、MongoDBのようなシステムでは、私は200Kのオブジェクトのように挿入します。

{ hash: '3736b5da857a4c7b9b046f326004803a', 
    name: 'inia, looked up one of the more obscure Latin words, consectetur, from a Lorem I', 
    description: ', looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of ', 
    tags: [ 'pc', 'pc', 'hd', 'mp4' ], 
    languages: [ 'fre', 'jap', 'deu' ] } 

挿入は2つのCESで100K arroundの、信じられないほどだったが、...ここでは実験である:

const Db = require('tingodb')({cacheSize: 60000, cacheMaxObjSize: 4096}).Db 
const assert = require('assert') 
const crypto = require('crypto') 
var db = new Db('./', {}) 

// Fetch a collection to insert document into 
var collection = db.collection("batch_document_insert_collection_safe") 

let t0 = new Date().getTime() 
collection.find({ tags: 'video' }).toArray(function(err, docs) { 
    console.log(err) 
    console.log(docs) 
    let t1 = new Date().getTime() 
    console.log('time: ' + (t1-t0)) 
}) 
200K DBでこれを実行する

通常であるかどうかを38 SECONDS秒の合計が知らないコストが...

そしてaladbについて、私はそれをテストし、うまく機能し

、I別の実験をしてみてください。パフォーマンスは良く、sqlite3と似ていますが、いくつかの検索では、sqliteよりも2倍遅いです(LIKE%文字列%を使用してエンジンを停止します)。

EDIT 2:Linuxマシンでabコマンド(ab -n 10000 -c 50 http://machine.tst:13375/library/search?tags=lorem)を使用して複数のリクエストをシミュレートした後、最終的にsqlite3ライブラリを使用していますが、開始時に1つのアディションテーブル)、テーブル内で処理された要求応答を格納します(id(INT), hash(VARCHAR), object(TEXT), last(NUMBER))。

初めてリクエストデータを使用してユニークなハッシュ( "GET" + "/ a/b/c" + JSON(requestData))を作成し、jsonがレスポンスをエンコードしました。通常の速度で、次の1つはmemcacheまたはそれに類似したDBを使用するようなものですが、現在は10リクエスト/秒から450リクエスト/秒にCPU使用率10%で取得しています。

とにかく、キャッシュされた行の最後の列をチェックして古い要求を削除し、メモリの問題を解消するウォッチャイベントを実行しますが、1つの要求で1回だけパラメータが複数回変更され、だから、私はメモリの使用法は大きく成長しないと思います。

将来の場合、私は私がしようとsqlite3のよりも、いくつかの優れた埋め込みオプションを発見し、DBエンジンを変更した場合

+1

「AlaSQL」(https://github.com/agershun/alasql)はどうですか? – num8er

答えて

2

パフォーマンスはかなり良いですし、あなたのユースケースのためにそれが見えますNode-LMDB

LMDBをお試しください理想的なものになります。クライアントあたり1,000,000行/秒を達成できました。

関連する問題