35

我在本地机器上做了简单的性能测试,这是 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?

4

4 回答 4

45

来自redis 文档

Redis 是一个服务器:所有命令都涉及网络或 IPC 往返。将其与 SQLite、Berkeley DB、Tokyo/Kyoto Cabinet 等嵌入式数据存储进行比较是没有意义的……因为大多数操作的成本恰恰是由网络/协议管理主导的。

尽管在某些情况下承认速度问题,但这确实是有道理的。例如,在多个并行访问下,Redis 的性能可能比 sqlite 好得多。

适合工作的正确工具,有时是 redis,有时是 sqlite,有时是完全不同的东西。如果此速度测试正确显示了您的应用程序将实际执行的操作,那么 sqlite 将为您提供更好的服务,并且您执行此基准测试很好。

于 2012-06-26T22:14:10.873 回答
33

当前的答案提供了关于为什么 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 相当。

于 2013-08-29T09:16:31.597 回答
13

SQLite 非常快,您只需要一个 IO 操作(在 上commit)。Redis 在网络上执行的 IO 显着增加。更多的苹果对苹果的比较将涉及通过网络访问的关系数据库(如 MySQL 或 PostgreSQL)。

您还应该记住,SQLite 已经存在了很长时间并且已经高度优化。它受到ACID合规性的限制,但您实际上可以将其关闭(就像一些 NoSQL 解决方案所做的那样),并且更快地获得它。

于 2012-06-26T22:26:58.173 回答
11

刚刚注意到您没有为 redis 提交提交。使用管道可以减少时间:

[---测试 SQLITE---]

【sql总时间:0.669369935989】

[---测试 REDIS---]

【redis总耗时:2.39369487762】

于 2013-06-27T18:27:34.480 回答