为什么Postgres查询比Redis查询更快?

时间:2018-03-11 16:46:39

标签: django postgresql time redis

我正在学习Redis,以及它在内存数据库中的速度如何。在我的Django应用程序中,我有一个Postgres表,其中包含大约1500行。该模型只有两个字段'name'和'occurrence'。为了测试查询对象内存不足的速度,与我认为存储在光盘上的本地数据库相比,我创建了两个查询

  

1)使用Django对象管理器查询的简单顺序

     

2)Redis服务器上的ZRANGE命令,从a获取相同的项目   Redis排序集。

在进行两次查询后,我发现从Redis排序集中获取相同数量的项目所花费的时间比制作Postgres查询所花费的时间长250倍。这是为什么?

脚本

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

2 个答案:

答案 0 :(得分:3)

请记住,redis不是通用数据库。有一些查询或用途,其中一个老式的rdbms是要走的路,有些是redis超越rdbms。 Redis为您提供闪电般快速的读取和写入键值存储数据。即,“对于给定的单词,我想检索出现的次数”,而不是“我希望所有单词按出现次数排序。”

所以,例如:

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和内存带宽的速度似乎对全局性能不太重要,特别是对于小型对象。对于大型对象(> 10 KB),它可能会变得明显。通常,购买昂贵的快速内存模块以优化Redis并不具有成本效益。   Redis benchmarks

答案 1 :(得分:1)

您的测试正在构建数据库查询,但实际上并未执行它。将您的行更改为:

words = list(Word.objects.order_by('-occurrence'))

这将强制评估查询。 (有关详细信息,请参阅文档的this section。)