gpt4 book ai didi

sql - 运行 SQL 查询超时

转载 作者:行者123 更新时间:2023-12-03 06:20:38 24 4
gpt4 key购买 nike

我尝试使用 django ORM 的聚合功能在 MSSQL 2008R2 数据库上运行查询,但我不断收到超时错误。失败的查询(由 django 生成)如下。我尝试过直接在 SQL Management Studio 上运行它,它可以工作,但需要 3.5 分钟

它看起来确实聚合了一堆不需要的字段,但我不会,但这确实会导致它花费那么长时间。数据库也不是那么大,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 Server 首先对所有表进行交叉联接,产生大约 2.8 亿行和 6Gb 的数据。我认为这就是问题所在,但为什么会发生呢?

最佳答案

SQL Server 正在完全按照要求执行操作。不幸的是,Django 没有生成您想要的正确查询。看来您需要计算不同的数,而不仅仅是计算: Django annotate() multiple times causes wrong answers

至于为什么查询会这样工作:查询表示将四个表连接在一起。假设作者有 2 个捕获的票证、3 个分配的票证和 4 个观看的票证,则连接将返回 2*3*4 个票证,每个票证组合一个。不同的部分将删除所有重复项。

关于sql - 运行 SQL 查询超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17358372/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com