I made a script to compare query speeds between methods in the redis library.
As I understand it, I should not use redis.keys() because it's a blocking function. The preferred method is scan_iter(), which doesn't block. That makes sense. But I don't understand why scan_iter is so terribly slow.
This script uses three techniques to query a redis database.
- Use redis.keys() to get all of the keys. Use redis.mget() to get all the values.
- Use a for loop with redis.scan_iter and redis.get() to get the values. (Note I don't need keys, just values)
- Use redis.scan_iter() to get all of the keys. Use redis.mget() to get all the values.
Option 1 was by far the fastest. Option 2 was 20 to 30 times slower. Option 3 averaged 4 times slower.
Why is this? Have I written my code incorectly? Do I have the wrong method? Is the redis.keys() method actually the best choice?
from datetime import datetime
from time import sleep
import redis
r = redis.StrictRedis(host='192.168.3.16', port=6379, decode_responses=True, db= 0)
def query_keys():
start = datetime.now()
redis_keys = r.keys(pattern='*')
redis_keys = [x for x in redis_keys if not x.startswith('1_')]
values = r.mget(redis_keys)
end = datetime.now()
print(str(len(values)) + ' values queried in ' + str(end - start) + ' with keys and mget.')
def query_scaniter():
start = datetime.now()
values = []
for s in r.scan_iter():
if not s.startswith('1_'):
values.append(r.get(s))
end = datetime.now()
print(str(len(values)) + ' values queried in ' + str(end - start) + ' with scan_iter.')
def query_scaniter_mget():
start = datetime.now()
redis_keys = []
for s in r.scan_iter():
if not s.startswith('1_'):
redis_keys.append(s)
values = r.mget(redis_keys)
end = datetime.now()
print(str(len(values)) + ' values queried in ' + str(end - start) + ' with scan_iter and mget.')
for i in range(3):
query_keys()
query_scaniter()
query_scaniter_mget()
print('\n')
sleep(5)
Output:
3532 values queried in 0:00:00.046872 with keys and mget.
3532 values queried in 0:00:00.781314 with scan_iter.
3532 values queried in 0:00:00.109385 with scan_iter and mget.
3526 values queried in 0:00:00.031245 with keys and mget.
3522 values queried in 0:00:00.812616 with scan_iter.
3522 values queried in 0:00:00.125007 with scan_iter and mget.
3529 values queried in 0:00:00.031246 with keys and mget.
3531 values queried in 0:00:00.797011 with scan_iter.
3530 values queried in 0:00:00.109357 with scan_iter and mget.