3

我正在编写这个复杂的查询来返回一个大数据集,大约有 100,000 条记录。查询运行良好,直到我将此 OR 语句添加到 WHERE 子句:

AND(responses.StrategyFk = strategy.Id 或responses.StrategyFk 为空)

现在我明白了,将 or 语句放在那里会增加很多开销。

没有那个声明,只是:

AND 响应.StrategyFk = strategy.Id

查询在 15 秒内运行,但不返回任何没有 fk 链接策略的记录。

虽然我也想要这些记录。有没有更简单的方法可以使用简单的 where 语句来查找这两个记录?我不能只为空记录添加另一个 AND 语句,因为这会破坏前面的语句。有点不确定从这里去哪里。

这是我查询的下半部分。

FROM 
responses, subtestinstances, students, schools, items,
strategies, subtests

WHERE
subtestinstances.Id = responses.SubtestInstanceFk
AND subtestinstances.StudentFk = students.Id
AND students.SchoolFk = schools.Id
AND responses.ItemFk = items.Id
AND (responses.StrategyFk = strategies.Id Or responses.StrategyFk IS Null)
AND subtests.Id = subtestinstances.SubtestFk
4

2 回答 2

2

尝试使用显式JOINs:

...
FROM   responses a
       INNER JOIN subtestinstances b
               ON b.id = a.subtestinstancefk
       INNER JOIN students c
               ON c.id = b.studentfk
       INNER JOIN schools d
               ON d.id = c.schoolfk
       INNER JOIN items e
               ON e.id = a.itemfk
       INNER JOIN subtests f
               ON f.id = b.subtestfk
       LEFT JOIN strategies g
              ON g.id = a.strategyfk 
于 2012-11-30T17:20:34.477 回答
2

尝试:

SELECT ... FROM 
responses
JOIN subtestinstances ON subtestinstances.Id = responses.SubtestInstanceFk
JOIN students ON subtestinstances.StudentFk = students.Id
JOIN schools ON students.SchoolFk = schools.Id
JOIN items ON responses.ItemFk = items.Id
JOIN subtests ON subtests.Id = subtestinstances.SubtestFk
LEFT JOIN strategies ON responses.StrategyFk = strategies.Id

而已。不需要 OR 条件,因为这就是 LEFT JOIN 在这种情况下所做的。任何地方的response.StrategyFk IS NULL 都会导致与strategies表不匹配,并且会为此返回一行。

有关连接的简单说明,请参见此链接:http: //www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html

之后,如果您仍然遇到性能问题,那么您可以开始查看EXPLAIN SELECT ... ;输出并查找可能需要添加的索引。使用 Explain 优化查询 -- MySQL 手册

于 2012-11-30T17:21:44.117 回答