我有一個Django 1.8應用程序,我使用的是MSSQL數據庫,用pyodbc爲DB後端(使用「Django的pyodbc-蔚藍」模塊)。Django的性能問題排除
我有以下型號:
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個項目的設備ID列表。
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)))))
因此,使用在數據庫級別排除似乎並沒有被影響的查詢性能,但在Django,查詢運行較慢的6倍,如果我加入排除部分。什麼可能導致這個?
您可能會指出您正在使用的數據庫後端。 (即pyodbc實現或Django-mssql) – Ringil
@Ringil感謝您的建議,使用該信息更新了問題 –