为什么我的MySQL查询使用Subselect挂起?
以下查询挂起:尽管单独执行的子查询没有问题 我不知道如何使解释表看起来很好。如果有人告诉我,我会把它清理干净为什么我的MySQL查询使用Subselect挂起?,mysql,subquery,Mysql,Subquery,以下查询挂起:尽管单独执行的子查询没有问题 我不知道如何使解释表看起来很好。如果有人告诉我,我会把它清理干净 select sum(grades.points)) as p, from assignments left join grades using (assignmentID) where gradeID IN (select grades.gradeID from assignments left join grades using (assignmentID) whe
select
sum(grades.points)) as p,
from assignments
left join grades using (assignmentID)
where gradeID IN
(select grades.gradeID
from assignments
left join grades using (assignmentID)
where ... grades.date <= '1255503600' AND grades.date >= '984902400'
group by assignmentID order by grades.date DESC);
我认为问题在于一年级表。。。有那么多行的类型似乎是原因。。一切都被编入索引
我上传了一张图片。无法正确设置格式:
一位评论者想要完整的where子句:
explain extended select count(assignments.assignmentID) as asscount, sum(TRIM(TRAILING '-' FROM grades.points)) as p, sum(assignments.points) as t
from assignments left join grades using (assignmentID)
where gradeID IN
(select grades.gradeID from assignments left join grades using (assignmentID) left join as_types on as_types.ID = assignments.type
where assignments.classID = '7815'
and (assignments.type = 30170 )
and grades.contactID = 7141
and grades.points REGEXP '^[-]?[0-9]+[-]?'
and grades.points != '-'
and grades.points != ''
and (grades.pointsposs IS NULL or grades.pointsposs = '')
and grades.date <= '1255503600'
AND grades.date >= '984902400'
group by assignmentID
order by grades.date DESC);
真的没有足够的信息来回答你的问题,你已经把一个。。。在WHERE子句的中间,这很奇怪。涉及的表有多大?索引是什么 话虽如此,如果in子句中的术语太多,您会看到性能严重下降。将中的用法替换为右连接 首先,in子句中的表as_类型不被使用。左加入它没有任何作用,所以摆脱它
这使得in子句只包含外部查询中的assignments and grades表。显然,修改赋值的where属于外部查询的where子句。您应该将所有where grades=where移动到左侧连接到grades的on子句中。如果子查询在单独执行时执行良好,请尝试使用连接而不是IN,如下所示:
select count(assignments.assignmentID) as asscount, sum(TRIM(TRAILING '-' FROM grades.points)) as p, sum(assignments.points) as t
from assignments left join grades using (assignmentID)
join
(select grades.gradeID from assignments left join grades using (assignmentID) left join as_types on as_types.ID = assignments.type
where assignments.classID = '7815'
and (assignments.type = 30170 )
and grades.contactID = 7141
and grades.points REGEXP '^[-]?[0-9]+[-]?'
and grades.points != '-'
and grades.points != ''
and (grades.pointsposs IS NULL or grades.pointsposs = '')
and grades.date <= '1255503600'
AND grades.date >= '984902400'
group by assignmentID
order by grades.date DESC) using (gradeID);
超级混乱,但是:谢谢大家的帮助
SELECT *
FROM grades
LEFT JOIN assignments ON grades.assignmentID = assignments.assignmentID
RIGHT JOIN (
SELECT g.gradeID
FROM assignments a
LEFT JOIN grades g
USING ( assignmentID )
WHERE a.classID = '7815'
AND (
a.type =30170
)
AND g.contactID =7141
g.points
REGEXP '^[-]?[0-9]+[-]?'
AND g.points != '-'
AND g.points != ''
AND (
g.pointsposs IS NULL
OR g.pointsposs = ''
)
AND g.date <= '1255503600'
AND g.date >= '984902400'
GROUP BY assignmentID
ORDER BY g.date DESC
) AS t1 ON t1.gradeID = grades.gradeID
这个查询有点难理解,但我怀疑根本不需要子查询。 看起来您的查询基本上是这样的:
SELECT FOO()
FROM assignments LEFT JOIN grades USING (assignmentID)
WHERE gradeID IN
(
SELECT grades.gradeID
FROM assignments LEFT JOIN grades USING (assignmentID)
WHERE your_conditions = TRUE
);
但是,在子查询的where子句中,您并没有做任何真正有趣的事情。
我怀疑更像
SELECT FOO()
FROM assignments LEFT JOIN grades USING (assignmentID)
GROUP BY groupings
WHERE your_conditions_with_some_tweaks = TRUE;
这样也行
如果我这里缺少一些关键的逻辑,请回复,我将编辑/删除这篇文章。请参阅中无法忍受的缓慢:
假设您使用一个真实的数据库,即除MySQL之外的任何数据库,但我将以Postgres为例执行此查询:
SELECT * FROM ta WHERE aid IN (SELECT subquery)
实际数据库将查看子查询并估计其行数:
如果行数很小,比如说不到几百万
它将运行子查询,然后构建ID的内存散列,这也使它们唯一,这是in的一个特性
然后,如果从ta中提取的行数是ta的一小部分,它将使用合适的索引来提取行。或者,如果选择了表的主要部分,它只需完全扫描它,然后在哈希中查找每个id,这非常快
但是,如果子查询行数相当大
数据库可能会将其重写为合并联接,为子查询添加唯一的Sort+
但是,您使用的是MySQL。在这种情况下,它不会执行任何操作,它将为表的每一行重新执行子查询,因此需要1000年的时间。很抱歉。请使用语法hilighting并对代码进行结构化,我看不懂:我修复了查询,但我不知道如何将表格式化。我需要使用html表格标签吗?@Stephanie:请参阅问题中格式良好的表格的示例。我想你说的“挂起”是指没有等待足够长的时间来完成查询。这些表格真的很大,从几千到几十万。索引位于我在where子句中使用的所有内容上。。。在我认为会把它弄得乱七八糟的地方,用5或6个不相关的语句代替。我将把它附加到末尾。我一直在试图找到如何执行您的建议:从表中选择内容右键连接选择内容,但我不知道如何将括号中的内容与外部查询关联起来。这个答案很古老,但对我帮助很大。我必须针对一个旧的MySQL5.0数据库工作,您发布的链接提供了一个解决慢速查询的方法。