У меня есть приложение Django 1.8, и я использую базу данных MsSQL с pyodbc в качестве бэкэнда db (используя модуль «django-pyodbc-azure»).Ошибка производительности с django exclude
У меня есть следующие модели:
class Branch(models.Model):
name = models.CharField(max_length=30)
startTime = models.DateTimeField()
class Device(models.Model):
uid = models.CharField(max_length=100, primary_key=True)
type = models.CharField(max_length=20)
firstSeen = models.DateTimeField()
lastSeen = models.DateTimeField()
class Session(models.Model):
device = models.ForeignKey(Device)
branch = models.ForeignKey(Branch)
start = models.DateTimeField()
end = models.DateTimeField(null=True, blank=True)
мне нужно запросить модель сеанса, и я хочу, чтобы исключить некоторые записи с определенными значениями устройств. Поэтому я выпускаю следующий запрос:
sessionCount = Session.objects.filter(branch=branch)
.exclude(device__in=badDevices)
.filter(end__gte=F('start')+timedelta(minutes=30)).count()
badDevices - это предварительно заполненный список идентификаторов устройств, насчитывающий около 60 наименований.
badDevices = ['id-1', 'id-2', ...]
Этот запрос занимает около 1,5 секунд. Если я удалю исключение из запроса, он займет около 250 миллисекунд.
Я напечатал сгенерированный sql для этого набора запросов и попробовал его в моем клиенте базы данных. Там обе версии выполнены примерно за 250 миллисекунд.
Это сгенерированный SQL:
SELECT [session].[id], [session].[device_id], [session].[branch_id], [session].[start], [session].[end]
FROM [session]
WHERE ([session].[branch_id] = my-branch-id AND
NOT ([session].[device_id] IN ('id-1', 'id-2', 'id-3',...)) AND
DATEPART(dw, [session].[start]) = 1
AND [session].[end] IS NOT NULL AND
[session].[end] >= ((DATEADD(second, 600, CAST([session].[start] AS datetime)))))
Таким образом, с помощью исключения в уровне базы данных не кажется, не влияет на производительность запросов, но в Джанго, запрос выполняется в 6 раз медленнее, если я добавляю исключить часть. Что может быть причиной этого?
Возможно, вам будет полезно указать, какой БД вы используете. (т. е. реализация pyodbc или Django-mssql) – Ringil
@Ringil благодарит за предложение, обновил вопрос с помощью этой информации. –