为什么我的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数据库工作,您发布的链接提供了一个解决慢速查询的方法。