我想使用django ORM的聚合功能在MSSQL 2008R2数据库上运行查询,但我不断收到超时错误。下面是失败的查询(由django生成)。我试过运行它指挥SQL管理工作室,它的工作原理,但需要3.5分钟超时运行SQL查询
它看起来是聚合在一堆领域,它不需要,但我不会有真的会导致它需要很长时间。数据库也不是那么大,auth_user
有9条记录,ticket_ticket
有1210和ticket_watchers
有1876.有什么我失踪?
SELECT
[auth_user].[id],
[auth_user].[password],
[auth_user].[last_login],
[auth_user].[is_superuser],
[auth_user].[username],
[auth_user].[first_name],
[auth_user].[last_name],
[auth_user].[email],
[auth_user].[is_staff],
[auth_user].[is_active],
[auth_user].[date_joined],
COUNT([tickets_ticket].[id]) AS [tickets_captured__count],
COUNT(T3.[id]) AS [assigned_tickets__count],
COUNT([tickets_ticket_watchers].[ticket_id]) AS [tickets_watched__count]
FROM
[auth_user]
LEFT OUTER JOIN [tickets_ticket] ON ([auth_user].[id] = [tickets_ticket].[capturer_id])
LEFT OUTER JOIN [tickets_ticket] T3 ON ([auth_user].[id] = T3.[responsible_id])
LEFT OUTER JOIN [tickets_ticket_watchers] ON ([auth_user].[id] = [tickets_ticket_watchers].[user_id])
GROUP BY
[auth_user].[id],
[auth_user].[password],
[auth_user].[last_login],
[auth_user].[is_superuser],
[auth_user].[username],
[auth_user].[first_name],
[auth_user].[last_name],
[auth_user].[email],
[auth_user].[is_staff],
[auth_user].[is_active],
[auth_user].[date_joined]
HAVING
(COUNT([tickets_ticket].[id]) > 0 OR COUNT(T3.[id]) > 0)
编辑:
下面是相关的索引(不包括在查询中不使用):
auth_user.id (PK)
auth_user.username (Unique)
tickets_ticket.id (PK)
tickets_ticket.capturer_id
tickets_ticket.responsible_id
tickets_ticket_watchers.id (PK)
tickets_ticket_watchers.user_id
tickets_ticket_watchers.ticket_id
编辑2:
位的后实验中,我发现以下查询是导致执行速度慢的最小问题:
SELECT
COUNT([tickets_ticket].[id]) AS [tickets_captured__count],
COUNT(T3.[id]) AS [assigned_tickets__count],
COUNT([tickets_ticket_watchers].[ticket_id]) AS [tickets_watched__count]
FROM
[auth_user]
LEFT OUTER JOIN [tickets_ticket] ON ([auth_user].[id] = [tickets_ticket].[capturer_id])
LEFT OUTER JOIN [tickets_ticket] T3 ON ([auth_user].[id] = T3.[responsible_id])
LEFT OUTER JOIN [tickets_ticket_watchers] ON ([auth_user].[id] = [tickets_ticket_watchers].[user_id])
GROUP BY
[auth_user].[id]
奇怪的是,如果我在上面注释掉任意两条线,它在更短的运行是1秒,但它似乎并没有问题我删除哪些行(虽然很明显,我无法删除没有也删除相关SELECT行的连接)。
编辑3:
其产生这种情况的Python代码是:
User.objects.annotate(
Count('tickets_captured'),
Count('assigned_tickets'),
Count('tickets_watched')
)
一看执行计划显示,SQL服务器第一次做的所有表中的交叉联接,产生约2.8亿行,以及6Gb的数据。我认为这是问题所在,但为什么会发生?
你有什么样的索引在桌子上? –
@NenadZivkovic无论django加入了什么 - 但好点,我会检查它们。 – aquavitae
你说得对,它需要很长时间。我会得到执行计划来看看它,并为io和时间设置统计信息,以查看是什么阻止了它。你还可以发布导致这个查询的代码吗?查询对我来说没有多大意义。 –