MySQL优化子查询

时间:2011-10-02 09:45:58

标签: mysql performance join subquery

我想优化这个查询(因为子查询通常不会很快),但我输了,因为我无法使用更好的性能连接来重写它,你能帮助mi吗?

SELECT id, company, street, number, number_addition, postalcode, telephone
FROM clients
    WHERE (postalcode BETWEEN '1000' AND '9000') AND street = (
        SELECT DISTINCT street FROM clients WHERE (postalcode BETWEEN '1000' AND '9000') AND postalcode <= (
            SELECT MIN(postalcode) FROM clients WHERE street = 'Main Street' AND     (postalcode BETWEEN '1000' AND '9000'))
        ORDER BY postalcode DESC LIMIT 1, 1)
ORDER BY postalcode DESC, street DESC, number DESC, number_addition DESC, telephone DESC
LIMIT 1

感谢您的时间。

1 个答案:

答案 0 :(得分:1)

SELECT DISTINCT street ORDER BY postalcode没有意义(我认为是无效的ANSI SQL),除非postalcode在功能上依赖于street - 我不认为它是,如果它是你的获得最低邮政编码在主街上内部子选择是没有意义的。 MySQL会让你逃脱它,但结果会不一致。你想在这说什么?

我不认为这应该特别慢,因为你所拥有的不是一个从属子查询;子查询只执行一次而不是每个外行重复执行。您可以将其重写为三个单独的查询 -

  1. 在大街上获得最低的邮政编码;
  2. 获得第二高邮政编码低于(1)(不一致)的街道;
  3. 获取街道上客户的详细信息(2)。
  4. 执行没有区别。 (事实上​​,为了清晰起见,最好这样做。)

    可以将这些重写为连接,使用自我左连接而不是空来获取最小值/最大值,但我不认为你会获得对于这个例子来说它的任何东西都会因为两个级别的加入和第二个最高要求而变得非常混乱。这个查询在实践中特别慢吗? EXPLAIN看起来像什么?您是否已将postalcodestreet编入索引?