@ Решение Сэма Одио послужило хорошей отправной точкой, но в методологии есть несколько недостатков, а именно:
- Случайный IP-адрес может в конечном итоге совпадать с 0 или очень малорезультаты
- Исключение может исказить результаты, поэтому мы должны стремиться избегать обработки исключений
Поэтому вместо того, чтобы фильтровать что-то, что может соответствовать, я решил исключить то, что определенно не будетсовпадение, надеюсь, по-прежнему избегая кеша БД, но также обеспечивая такое же количество строк.
Я тестировал только на локальной базе данных MySQL с набором данных:
>>> Session.objects.all().count()
40219
Код синхронизации:
import timeit
base = """
import random
import string
from django.contrib.sessions.models import Session
never_match = ''.join(random.choice(string.ascii_uppercase) for _ in range(10))
sessions = Session.objects.exclude(session_key=never_match){}
if sessions:
pass
"""
s = base.format('count')
query_variations = [
"",
".exists()",
".count()",
"[0]",
]
for variation in query_variations:
t = timeit.Timer(stmt=base.format(variation))
print "{} => {:02f} usec/pass".format(variation.ljust(10), 1000000 * t.timeit(number=100)/100000)
выходы:
=> 1390.177710 usec/pass
.exists() => 2.479579 usec/pass
.count() => 22.426991 usec/pass
[0] => 2.437079 usec/pass
Итак, вы можете видеть, что count()
примерно в 9 раз медленнее, чем exists()
для этого набора данных.
[0]
isтакже быстро, но требует обработки исключений.