请考虑以下查询:
SELECT
...
FROM table1
LEFT JOIN table2 ...
LEFT JOIN table3 ...
LEFT JOIN table4 ...
LEFT JOIN table5 ...
LEFT JOIN
(
SELECT id, COUNT(*) as qty FROM other WHERE ... GROUP BY id
) temp ON temp.id = table1.id
WHERE temp.qty = 123
GROUP BY table1.id
此查询非常慢,但是当我执行
时SELECT id, COUNT(*) as qty FROM other WHERE ... GROUP BY id
单独来说,它的速度非常快,它只返回少量(20-30)行...
我当前的解决方案是带索引的临时表,我用数据填充它,然后我使用join:
DROP TABLE IF EXISTS tmp_counts;
CREATE TABLE tmp_counts id INT(11), qty INT(11) ...
INSERT INTO tmp_counts (id,qty) (SELECT id, COUNT(*) as qty FROM other WHERE ... GROUP BY id);
SELECT
...
FROM table1
LEFT JOIN table2 ...
LEFT JOIN table3 ...
LEFT JOIN table4 ...
LEFT JOIN table5 ...
LEFT JOIN tmp_counts ON tmp_counts.id = table1.id
WHERE tmp_counts.qty = 123
GROUP BY table1.id
它工作得非常快,但我觉得这是一个难看的解决方案。
MySQL真的是那么愚蠢我需要自己手动做mysql工作吗?
答案 0 :(得分:3)
MySQL并非 愚蠢。优化数据库很复杂。事实上,当你考虑它时,很少有软件可以在如此多种不同的情况下进行这样的优化。程序和面向对象语言 - 告诉他们该做什么。在SQL中,我们说出我们想要的东西,让优化器找到最好的。反过来,最好的方法可能在很大程度上取决于基础数据。
有时优化器是错误的。有时我们可以说服它。这里的问题很可能是连接顺序或连接算法的选择。解决这类问题的一种方法是用select
中的相关子查询替换子查询:
选择
SELECT . . .,
(SELECT COUNT(*)
FROM other
WHERE . . . AND
other.id = table1.id
) as qty
...
FROM table1
LEFT JOIN table2 ...
LEFT JOIN table3 ...
LEFT JOIN table4 ...
LEFT JOIN table5 ...
GROUP BY table1.id;
反过来,可以通过在other
上创建索引来进一步优化。至少,这将是other.id
。