以下查询挂起:(虽然分别执行的子查询很好)
我不知道如何使解释表看起来不错。如果有人告诉我,我会清理它。
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);
我认为问题出在第一等级表中......带有那么多行的类型ALL似乎是原因..所有内容都被编入索引。
我将表格上传为图片。无法正确格式化: http://imgur.com/AjX34.png
评论者需要完整的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);
答案 0 :(得分:2)
答案 1 :(得分:1)
超级凌乱,但是:(感谢大家的帮助)
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
答案 2 :(得分:1)
假设您使用Real Database(即除了MySQL之外的任何数据库,但我将使用Postgres作为示例)来执行此查询:
SELECT * FROM ta WHERE aid IN (SELECT subquery)
Real Database会查看子查询并估计其rowcount:
它将运行子查询,然后构建一个内存中的ids哈希值,这也使它们成为唯一的,这是IN()的一个特性。
然后,如果从ta拉出的行数是ta的一小部分,它将使用合适的索引来拉动行。或者,如果选择了表的主要部分,它将完全扫描它,并在哈希中查找每个id,这非常快。
数据库可能会将其重写为合并JOIN,为子查询添加Sort + Unique。
但是,您正在使用MySQL。在这种情况下,它不会执行任何操作(它将为表的每一行重新执行子查询),因此需要1000年。遗憾。
答案 3 :(得分:0)
确实没有足够的信息来回答你的问题,你已经把...放在where子句的中间,这很奇怪。涉及的表有多大,索引是什么?
话虽如此,如果in子句中的术语太多,您可以看到性能严重下降。 使用右连接替换使用in 。
对于初学者,不使用in子句中的表 as_types 。左加入它没有任何意义,所以摆脱它。
这使得in子句只包含外部查询中的赋值和成绩表。显然,修改赋值属于外部查询的where子句。您应该将 grade = whatever 的所有内容移动到左连接的on子句中以获得成绩。
答案 4 :(得分:0)
如果子查询在单独执行时执行正常,那么尝试使用JOIN而不是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);
答案 5 :(得分:0)
查询有点难以遵循,但我怀疑子查询根本不是必需的。 看起来您的查询基本上就是这样:
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;
也可以。
如果我在这里遗漏了一些关键逻辑,请回复评论,我会编辑/删除这篇文章。