简体   繁体   English

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

[英]Why is SQLite faster than Redis in this simple benchmark?

I have done simple performance test on my local machine, this is python script: 我在我的本地机器上做了简单的性能测试,这是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)

I expected redis to perform faster, but the result shows that it much more slower: 我希望redis的执行速度更快,但结果表明它更慢:

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

So, the redis is memory based, what about sqlite? 所以,redis是基于内存的,sqlite怎么样? Why redis is so slow? 为什么redis这么慢? When I need to use redis and when I need to use sqlite? 当我需要使用redis并且需要使用sqlite时?

from the redis documentation 来自redis文档

Redis is a server: all commands involve network or IPC roundtrips. Redis是一个服务器:所有命令都涉及网络或IPC往返。 It is meaningless to compare it to embedded data stores such as SQLite, Berkeley DB, Tokyo/Kyoto Cabinet, etc ... because the cost of most operations is precisely dominated by network/protocol management. 将它与嵌入式数据存储(例如SQLite,Berkeley DB,Tokyo / Kyoto Cabinet等)进行比较是没有意义的......因为大多数操作的成本恰好由网络/协议管理决定。

Which does make sense though it's an acknowledgement of speed issues in certain cases. 虽然在某些情况下确认速度问题,但这确实有意义。 Redis might perform a lot better than sqlite under multiples of parallel access for instance. 例如,在多个并行访问的情况下,Redis可能比sqlite执行得更好。

The right tool for the right job , sometimes it'll be redis other times sqlite other times something totally different. 适合正确工作的正确工具 ,有时它会在其他时间重新发布,而其他时候则完全不同。 If this speed test is a proper showing of what your app will realistically do then sqlite will serve you better and it's good that you did this benchmark. 如果这个速度测试能够正确显示你的应用程序将会切实做什么,那么sqlite会更好地为你服务,你做这个基准测试是件好事。

The current answers provide insight as to why Redis loses this particular benchmark, ie network overhead generated by every command executed against the server, however no attempt has been made to refactor the benchmark code to accelerate Redis performance. 目前的答案提供了解决Redis为何失去这个特定基准的原因,即对服务器执行的每个命令产生的网络开销,但是没有尝试重构基准代码以加速Redis性能。

The problem with your code lies here: 代码的问题在于:

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

You incur 100,000 round-trips to the Redis server, resulting in great I/O overhead. 您需要100,000次往返Redis服务器,这会带来很大的I / O开销。

This is totally unnecessary as Redis provides "batch" like functionality for certain commands, so for SET there is MSET, so you can refactor the above to: 这是完全没必要的,因为Redis为某些命令提供了“批处理”功能,所以对于SET有MSET,所以你可以将上面的内容重构为:

r.mset(data)

From 100,000 server trips down to 1. You simply pass the Python dictionary as a single argument and Redis will atomically apply the update on the server. 从100,000次服务器跳转到1.您只需将Python字典作为单个参数传递,Redis将在服务器上自动应用更新。

This will make all the difference in your particular benchmark, you should see Redis perform at least on par with SQLite. 这将使您的特定基准测试产生重大影响,您应该看到Redis的性能至少与SQLite相当。

SQLite is very fast, and you're only requiring one IO action (on the commit ). SQLite非常快,你只需要一个IO动作(在commit )。 Redis is doing significantly more IO since it's over the network. 由于它通过网络,Redis正在做更多的IO。 A more apples-to-apples comparison would involve a relational database accessed over a network (like MySQL or PostgreSQL). 更多的苹果与苹果的比较将涉及通过网络(如MySQL或PostgreSQL)访问的关系数据库。

You should also keep in mind that SQLite has been around for a long time and is very highly optimized. 你也应该记住,SQLite的已经存在了很长一段时间, 非常高度优化。 It's limited by ACID compliance, but you can actually turn that off (as some NoSQL solutions do), and get it even faster. 它受到ACID合规性的限制,但实际上您可以将其关闭 (如某些NoSQL解决方案所做的那样),并使其更快。

Just noticed that you did not pipeline the commit for redis. 刚注意到你没有管道redis的提交。 Using piplines the time reduces: 使用piplines减少时间:

[---Testing SQLITE---] [---测试SQLITE ---]

[Total time of sql: 0.669369935989] [sql的总时间:0.669369935989]

[---Testing REDIS---] [---测试REDIS ---]

[Total time of redis: 2.39369487762] [redis总时间:2.39369487762]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM