在这个简单的基准测试中,为什么SQLite比Redis更快?

时间:2012-06-26 22:07:42

标签: python sql 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?

4 个答案:

答案 0 :(得分:36)

来自redis documentation

  

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

虽然它在某些情况下是对速度问题的承认,但它确实有意义。例如,在多个并行访问的情况下,Redis可能比sqlite执行得更好。

适合正确工作的正确工具,有时它会在其他时间重新发布,而其他时候则完全不同。如果这个速度测试能够正确显示你的应用程序将会切实做什么,那么sqlite会为你提供更好的服务,并且你做这个基准测试是件好事。

答案 1 :(得分:28)

目前的答案提供了有关Redis失去此特定基准的原因,即针对服务器执行的每个命令产生的网络开销,但是没有尝试重构基准代码以加速Redis性能。

您的代码存在问题:

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

您需要100,000次往返Redis服务器,这会带来很大的I / O开销。

这完全没必要,因为Redis为某些命令提供了“批处理”功能,所以对于SET有MSET,所以你可以将上面的内容重构为:

r.mset(data)

从100,000次服务器旅行减少到1.您只需将Python字典作为单个参数传递,Redis将在服务器上自动应用更新。

这将使您的特定基准测试产生重大影响,您应该看到Redis的性能至少与SQLite相当。

答案 2 :(得分:10)

SQLite非常快,你只需要一个IO动作(在commit上)。由于它通过网络,Redis正在做更多的IO。更多的苹果与苹果的比较将涉及通过网络(如MySQL或PostgreSQL)访问的关系数据库。

您还应该记住,SQLite已经存在了很长时间,并且非常高度优化。它受到ACID合规性的限制,但您实际上可以turn that off(正如一些NoSQL解决方案所做的那样),并且速度更快。

答案 3 :(得分:8)

注意到你没有管道redis的提交。使用piplines可以缩短时间:

[---测试SQLITE ---]

[sql的总时间:0.669369935989]

[---测试REDIS ---]

[redis总时间:2.39369487762]