web-dev-qa-db-ja.com

この単純なベンチマークでSQLiteがRedisより高速なのはなぜですか?

ローカルマシンで簡単なパフォーマンステストを実行しました。これはpythonスクリプトです:

import redis
import sqlite3
import time

data = {}
N = 100000

for i in xrange(N):
    key = "key-"+str(i)
    value = "value-"+str(i)
    data[key] = value

r = redis.Redis("localhost", db=1)
s = sqlite3.connect("testDB")
cs = s.cursor()

try:
    cs.execute("CREATE TABLE testTable(key VARCHAR(256), value TEXT)")
except Exception as excp:
    print str(excp)
    cs.execute("DROP TABLE testTable")
    cs.execute("CREATE TABLE testTable(key VARCHAR(256), value TEXT)")

print "[---Testing SQLITE---]"
sts = time.time()
for key in data:
    cs.execute("INSERT INTO testTable VALUES(?,?)", (key, data[key]))
    #s.commit()
s.commit()
ste = time.time()
print "[Total time of sql: %s]"%str(ste-sts)

print "[---Testing REDIS---]"
rts = time.time()
r.flushdb()# for empty db
for key in data:
    r.set(key, data[key])
rte = time.time()
print "[Total time of redis: %s]"%str(rte-rts)

Redisはより高速に動作することを期待していましたが、結果ははるかに遅いことを示しています。

[---Testing SQLITE---]
[Total time of sql: 0.615846157074]
[---Testing REDIS---]
[Total time of redis: 10.9668009281]

では、redisはメモリベースですが、sqliteはどうですか?なぜredisはとても遅いのですか? redisを使用する必要がある場合と、sqliteを使用する必要がある場合

28
torayeff

redisのドキュメント から

Redisはサーバーです。すべてのコマンドはネットワークまたはIPC=ラウンドトリップを含みます。SQLite、Berkeley DB、Tokyo/Kyoto Cabinetなどの埋め込みデータストアと比較しても意味がありません。ほとんどの操作のコストは、ネットワーク/プロトコル管理によって正確に支配されます。

これは、特定の場合の速度の問題を認めたものですが、理にかなっています。たとえば、Redisは、複数の並列アクセスでsqliteよりもはるかに優れたパフォーマンスを発揮する可能性があります。

適切な仕事のための適切なツール、それは時々それが他の時にsqlite他の時に全く異なる何かを再実行するでしょう。この速度テストがアプリが実際に行うことの適切な表示である場合、sqliteはより良いサービスを提供し、このベンチマークを実行したことは良いことです。

38
Harald Brinkhof

現在の回答は、Redisがこの特定のベンチマーク、つまりサーバーに対して実行されたすべてのコマンドによって生成されるネットワークオーバーヘッドを失う理由に関する洞察を提供しますが、Redisのパフォーマンスを加速するためにベンチマークコードをリファクタリングする試みは行われていません。

あなたのコードの問題はここにあります:

for key in data:
    r.set(key, data[key])

Redisサーバーへの往復が100,000回発生し、I/Oオーバーヘッドが大幅に増加します。

Redisは特定のコマンドに「バッチ」のような機能を提供するため、これは完全に不要です。SETにはMSETがあり、上記を次のようにリファクタリングできます。

r.mset(data)

100,000サーバーから1にトリップします。Python辞書を単一の引数として渡すだけで、Redisがサーバーに更新をアトミックに適用します。

これにより、特定のベンチマークですべての違いが生まれます。Redisが少なくともSQLiteと同等のパフォーマンスを発揮するはずです。

28
user2014979

SQLiteは非常に高速で、必要なのは1つのIOアクション(commitに対して)だけです。Redisは大幅に多くのことを実行していますIOより多くのアップル間の比較には、ネットワーク(MySQLやPostgreSQLなど)を介してアクセスされるリレーショナルデータベースが含まれます。

SQLiteは長い間使用されており、very高度に最適化されていることにも注意してください。 [〜#〜] acid [〜#〜] コンプライアンスによって制限されますが、実際には オフにする (一部のNoSQLソリューションと同様)で、さらに高速に取得できます。

10
Brendan Long

Redisのコミットをパイプライン処理していないことに気づきました。ピップラインを使用すると時間が短縮されます。

[--- SQLITEのテスト---]

[SQLの合計時間:0.669369935989]

[--- REDISのテスト---]

[redisの合計時間:2.39369487762]

8
basti