Подтвердить что ты не робот

Почему SQLite быстрее, чем Redis, в этом простом бенчмарке?

Я сделал простой тест производительности на своей локальной машине, это python script:

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?

4b9b3361

Ответ 1

из redis documentation

Redis - это сервер: все команды включают в себя сетевые или IPC-обратные вызовы. Нецелесообразно сравнивать его со встроенными хранилищами данных, такими как SQLite, Berkeley DB, Tokyo/Kyoto Cabinet и т.д.... потому что стоимость большинства операций в основном зависит от управления сетью/протоколом.

Что имеет смысл, хотя это признание скоростных проблем в некоторых случаях. Например, Redis может работать намного лучше, чем sqlite при параллельном доступе к параллельному доступу.

Правильный инструмент для правильной работы, иногда это будет redis в других случаях, когда sqlite в других случаях что-то совершенно другое. Если этот тест скорости - это правильное отображение того, что будет делать ваше приложение, то sqlite будет служить вам лучше, и хорошо, что вы сделали этот тест.

Ответ 2

В текущих ответах дается представление о том, почему Redis теряет этот конкретный ориентир, то есть сетевые издержки, генерируемые каждой командой, выполненной против сервера, однако не было предпринято никаких попыток реорганизовать тестовый код для ускорения работы Redis.

Проблема с вашим кодом лежит здесь:

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

Вы получаете 100 000 обращений к серверу Redis, что приводит к большим издержкам ввода-вывода.

Это совершенно не нужно, так как Redis предоставляет "пакетные" функции для определенных команд, поэтому для SET есть MSET, поэтому вы можете реорганизовать выше:

r.mset(data)

От 100 000 попыток сервера до 1. Вы просто передаете словарь Python как один аргумент, а Redis будет атомически применять обновление на сервере.

Это будет иметь значение для вашего конкретного теста, вы должны увидеть, что Redis выполняет по крайней мере наравне с SQLite.

Ответ 3

SQLite очень быстрый, и вам требуется только одно действие ввода-вывода (на commit). Redis делает значительно больше ввода-вывода, так как он по сети. Более сравнение яблок с яблоками будет включать реляционную базу данных, доступную через сеть (например, MySQL или PostgreSQL).

Вы также должны иметь в виду, что SQLite существует уже давно и очень оптимизирован. Он ограничен ACID, но вы можете отключить это (как это делают некоторые решения NoSQL), и получить его еще быстрее.

Ответ 4

Только что заметил, что вы не контрулировали commit для redis. С помощью трубопроводов время сокращается:

[--- Тестирование SQLITE ---]

[Общее время sql: 0.669369935989]

[--- Проверка REDIS ---]

[Общее время redis: 2.39369487762]