【问题标题】:Optimizing a where statement MYSQL优化where语句MYSQL
【发布时间】:2012-12-01 01:21:44
【问题描述】:

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

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

现在我明白了,将 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

【问题讨论】:

    标签: mysql sql optimization where


    【解决方案1】:

    尝试:

    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 在这种情况下所做的。任何地方的responses.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

    【讨论】:

    • 啊,非常感谢!这样效率高很多。看起来我应该从现在开始使用这种显式连接方法。
    • 完全正确;与其他人一起工作更容易,也更容易阅读和理解您正在尝试做的事情。
    【解决方案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 
    

    【讨论】:

    • 也感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 2021-11-22
    • 1970-01-01
    • 1970-01-01
    • 2013-05-09
    • 2010-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多