2012-11-30 95 views
3

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

AND(responses.StrategyFk = strategies.Id或者responses.StrategyFk IS 空)

现在我明白,把这个语句放在那里会增加很多开销。

没有这种说法,只是:

和responses.StrategyFk = strategies.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 

回答

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条件是真的需要的,因为这是左连接在这种情况下所做的。任何地方的响应.StrategyFk IS NULL将导致与strategies表不匹配,并且它将为此返回一行。

请参阅此链接一个简单的解释的加入:http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html

之后,如果你仍然遇到性能问题,那么你就可以开始看EXPLAIN SELECT ... ;输出,并寻找可能需要添加索引。 Optimizing Queries With Explain -- MySQL Manual

+0

Ahh非常感谢!这效率更高。看起来我应该从现在开始使用这种显式连接的方法。确切地说, – mmSQL

+0

;与其他人一起阅读和理解您要做的事情更容易。 –

2

尝试使用明确JOIN S:

... 
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 
+0

感谢您的帮助。 – mmSQL