我想优化这个查询(因为子查询一般来说并不快),但我迷路了,因为我无法使用对性能更好的连接重写它,你能帮我解决这个问题吗?
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
谢谢你们抽出时间。
最佳答案
SELECT DISTINCT street ORDER BY postalcode
没有意义(我认为这不是有效的 ANSI SQL),除非 postalcode
在功能上依赖于 street
——我不认为它是,因为如果它是,你的 get-lowest-postalcode-on-Main-Street 内部子选择就没有意义。 MySQL 会让你侥幸逃脱,但结果会不一致。你想在这里说什么?
我认为这不会特别慢,因为您拥有的不是依赖子查询;子查询只对每个外行执行一次,而不是重复执行。您可以将其重写为三个单独的查询 —
- 获取 Main Street 上最低的邮政编码;
- 获取第二大邮政编码低于 (1) 的街道(不一致);
- 获取街道上客户的详细信息 (2)。
执行没有区别。 (实际上,为了清楚起见,这样做可能更好。)
您可以将这些重写为连接,使用 self-left-joins-on-less-than-is-null 来获得最小值/最大值,但我认为您不会获得对于这个例子,它会变得非常困惑,因为它有两个级别的加入和第二高的要求。这个查询在实践中特别慢吗? EXPLAIN
是什么样子的?您是否已将 postalcode
和 street
编入索引?
关于MySQL 优化子查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7625646/