Django 为什么Postgres查询比Redis查询快?
我正在学习Redis,以及它是如何在内存数据库中快速发展的。在我的Django应用程序中,我有一个Postgres表,其中大约有1500行。该模型只有两个字段“name”和“occurrence”。为了测试查询内存不足的对象要比查询本地数据库快多少,我创建了两个查询 1) 使用Django对象管理器按查询简单排序 2) Redis服务器上的ZRANGE命令,从 Redis排序集 在进行两次查询之后,我发现从Redis排序集获取相同数量的项目所花费的时间是进行Postgres查询所花费的时间的250倍。为什么会这样 剧本Django 为什么Postgres查询比Redis查询快?,django,postgresql,time,redis,Django,Postgresql,Time,Redis,我正在学习Redis,以及它是如何在内存数据库中快速发展的。在我的Django应用程序中,我有一个Postgres表,其中大约有1500行。该模型只有两个字段“name”和“occurrence”。为了测试查询内存不足的对象要比查询本地数据库快多少,我创建了两个查询 1) 使用Django对象管理器按查询简单排序 2) Redis服务器上的ZRANGE命令,从 Redis排序集 在进行两次查询之后,我发现从Redis排序集获取相同数量的项目所花费的时间是进行Postgres查询所花费的时间的25
import json
import redis
import datetime
from django.http import HttpResponse
from django.shortcuts import render
from wikipedia.models import Word
redis_server = redis.Redis("localhost")
def get_word_results(request):
now = datetime.datetime.now()
words = Word.objects.all().order_by('-occurrence')
after = datetime.datetime.now()
diff = (after - now).total_seconds() * 1000
print(diff)
rnow = datetime.datetime.now()
words_redis = redis_server.zrange(name='myzset', start=0, end=-1, withscores=True)
rafter = datetime.datetime.now()
diff2 = (rafter - rnow).total_seconds() * 1000
print(diff2)
结果
0.199
48.048
记住,redis不是一个通用数据库。有些查询或使用传统的rdbms,有些则是redis超越rdbms的。Redis为您提供了对键值存储数据的闪电般快速读取和写入。i、 例如,“对于给定的单词,我希望检索出现的次数”,而不是“我希望所有单词都按出现的次数排序” 例如:
def prep_redis():
for word in Word.objects.all():
redis_server.set(word.name, word.occurrence)
def test_lookup_postgres(name):
# start = datetime.datetime.now()
p = Word.objects.get(name=name)
# end = datetime.datetime.now()
# diff = end - start
# print('postgres took %s ms' % (diff * 1000,))
return p.occurrence
def test_lookup_redis(name):
# start = datetime.datetime.now()
value = redis_server.get(name)
# end = datetime.datetime.now()
# diff = end - start
# print('redis took %s ms' % (diff * 1000,))
return value
def main():
from timeit import Timer
prep_redis()
r_timer = Timer(lambda: test_lookup_redis('sesame'))
p_timer = Timer(lambda: test_lookup_postgres('sesame'))
print('For 1000 runs, redis: %s' % (r_timer.timeit(number=1000),))
print('For 1000 runs, postgres: %s' % (p_timer.timeit(number=1000),))
在这里,我们期望redis比postgres更快
相比之下,redis对于较大的数据结构速度非常慢,因为序列化和反序列化数据所需的时间超过了I/O成本:
RAM的速度和内存带宽对于全局性能似乎不那么重要,尤其是对于小型对象。但对于大型对象(>10KB),它可能会变得引人注目。通常,购买昂贵的快速内存模块来优化Redis并不划算。
记住,redis不是一个通用数据库。有些查询或使用传统的rdbms,有些则是redis超越rdbms的。Redis为您提供了对键值存储数据的闪电般快速读取和写入。i、 例如,“对于给定的单词,我希望检索出现的次数”,而不是“我希望所有单词都按出现的次数排序” 例如:
def prep_redis():
for word in Word.objects.all():
redis_server.set(word.name, word.occurrence)
def test_lookup_postgres(name):
# start = datetime.datetime.now()
p = Word.objects.get(name=name)
# end = datetime.datetime.now()
# diff = end - start
# print('postgres took %s ms' % (diff * 1000,))
return p.occurrence
def test_lookup_redis(name):
# start = datetime.datetime.now()
value = redis_server.get(name)
# end = datetime.datetime.now()
# diff = end - start
# print('redis took %s ms' % (diff * 1000,))
return value
def main():
from timeit import Timer
prep_redis()
r_timer = Timer(lambda: test_lookup_redis('sesame'))
p_timer = Timer(lambda: test_lookup_postgres('sesame'))
print('For 1000 runs, redis: %s' % (r_timer.timeit(number=1000),))
print('For 1000 runs, postgres: %s' % (p_timer.timeit(number=1000),))
在这里,我们期望redis比postgres更快
相比之下,redis对于较大的数据结构速度非常慢,因为序列化和反序列化数据所需的时间超过了I/O成本:
RAM的速度和内存带宽对于全局性能似乎不那么重要,尤其是对于小型对象。但对于大型对象(>10KB),它可能会变得引人注目。通常,购买昂贵的快速内存模块来优化Redis并不划算。
您的测试正在构造数据库查询,但实际上并没有执行它。将您的线路更改为:
words = list(Word.objects.order_by('-occurrence'))
这将强制对查询进行求值。(有关更多详细信息,请参阅文档的一部分。)您的测试正在构造数据库查询,但实际上并没有执行它。将您的线路更改为:
words = list(Word.objects.order_by('-occurrence'))
这将强制对查询进行求值。(有关详细信息,请参阅文档的第页。)谢谢Kevin!你的两个答案都非常有助于我更好地理解这个问题。如果我能把这两个都标为答案,我会:)。谢谢凯文!你的两个答案都非常有助于我更好地理解这个问题。如果我能把这两个都标为答案,我会:)。谢谢两个,这真的很有帮助!谢谢2ps,这真的很有帮助!