如何在MySQL 4.1上加速这个SQL查询?

时间:2009-01-14 13:15:57

标签: mysql indexing performance

我有一个SQL查询需要很长时间才能在MySQL上运行(需要几分钟)。查询是针对一个超过1亿行的表运行的,所以我并不感到惊讶它的速度很慢。但理论上,应该可以加快速度,因为我真的只想从大表中取回行(让我们称之为A)在另一个表B中有一个引用。

所以我的查询是:

SELECT id FROM A, B where A.ref = B.ref;

(A有超过1亿行; B只有几千行)。

我添加了INDEXes:

alter table A add index(ref);
alter table B add index(ref);

但它仍然很慢(几分钟 - 我会对一分钟感到满意)。

不幸的是,我坚持使用MySQL 4.1.22,所以我无法使用视图。

我宁愿不将A中的所有相关行复制到一个单独的较小的表中,因为我需要的行会不时更改。另一方面,目前这是我能想到的唯一解决方案。

欢迎任何建议!

编辑:这是在我的查询上运行EXPLAIN的输出:

+----+-------------+------------------------+------+------------------------------------------+-------------------------+---------+------------------------------------------------+-------+-------------+
| id | select_type | table                  | type | possible_keys                            | key                     | key_len | ref                                            | rows  | Extra       |
+----+-------------+------------------------+------+------------------------------------------+-------------------------+---------+------------------------------------------------+-------+-------------+
|  1 | SIMPLE      | B                      | ALL  | B_ref,ref                                | NULL                    |    NULL | NULL                                           | 16718 | Using where |
|  1 | SIMPLE      | A                      | ref  | A_REF,ref                                | A_ref                   |       4 | DATABASE.B.ref                                 |  5655 |             |
+----+-------------+------------------------+------+------------------------------------------+-------------------------+---------+------------------------------------------------+-------+-------------+

(在编写我的原始查询示例时,我选择使用“ref”作为我的列名,这恰好与其中一种类型相同,但希望这不会太混乱......)

3 个答案:

答案 0 :(得分:2)

查询优化器可能已经尽力而为,但是在不太可能的情况下,它首先读取巨型表(A),您可以使用STRAIGHT_JOIN语法明确告诉它首先读取B:

SELECT STRAIGHT_JOIN id FROM B, A where B.ref = A.ref;

答案 1 :(得分:1)

从答案来看,您似乎正在使用SQL做最有效的事情。 A表似乎是一个大问题,如何将它分成三个单独的表,有点像本地版本的分片?或者,是否值得将B表非规范化为A表,假设B没有太多列?

最后,你可能只需购买一个更快的盒子来运行它 - 马力无法替代!

祝你好运。

答案 2 :(得分:0)

SELECT A FROM FROM JOIN B ON A.ref = B.ref

您可以通过使用适当类型的连接进一步优化,例如LEFT JOIN

http://en.wikipedia.org/wiki/Join_(SQL)