【发布时间】:2011-10-25 08:39:55
【问题描述】:
基本上我们对 Mysqls 的性能很满意,类似的查询可以在一瞬间完成。现在我们遇到了这个查询的问题
SELECT dc.id,dmr.art_id
FROM dmr
JOIN dma ON dma.id = dmr.dml_id
JOIN dc ON dc.id = dma.dc_id
WHERE dmr.art_id = 2285
提取 5021 行需要 50 秒。缺少索引可能是此类问题的最常见原因。所以我在 EXPLAIN 查询之前得到了这个查询计划,它表明只使用索引而不使用顺序扫描。
dmr 和 dma 表各有 300 万行,dc 有 6000 行。
+----+-------------+-------+--------+-------------------------------+----------------+---------+--------------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+-------------------------------+----------------+---------+--------------------+------+-------------+
| 1 | SIMPLE | dmr | ref | FKC33D5199F17E1825,ix_art_ref | ix_art_ref | 5 | const | 5021 | Using where |
| 1 | SIMPLE | dma | eq_ref | PRIMARY,FK8C6E1445153BBDC9 | PRIMARY | 8 | dev.dmr.dml_id | 1 | |
| 1 | SIMPLE | dc | eq_ref | PRIMARY | PRIMARY | 8 | dev.dma.dc_id | 1 | Using index |
+----+-------------+-------+--------+-------------------------------+----------------+---------+--------------------+------+-------------+
什么可能导致这个问题?
MySql 版本是 5.5,使用 InnoDB 作为引擎。 (只有 windows 上的默认参数)。
编辑
当我删除 where 子句时,mysql 立即返回(巨大的)结果集。 本例中的查询计划如下所示:
+----+-------------+-------+-------+----------------------------+--------------------+---------+------------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+----------------------------+--------------------+---------+------------+------+--------------------------+
| 1 | SIMPLE | dc | index | PRIMARY | FKAEB144C64FA71464 | 9 | NULL | 4037 | Using index |
| 1 | SIMPLE | dma | ref | PRIMARY,FK8C6E1445153BBDC9 | FK8C6E1445153BBDC9 | 9 | dev.dc.id | 263 | Using where; Using index |
| 1 | SIMPLE | dmr | ref | FKC33D5199F17E1825 | FKC33D5199F17E1825 | 9 | dev.dma.id | 1 | Using where |
+----+-------------+-------+-------+----------------------------+--------------------+---------+------------+------+--------------------------+
【问题讨论】:
-
你的 I/O 很可能被硬盘绑定了。将
innodb_buffer_pool大小变量增加到 RAM 的 70%。这样,部分工作数据集将保存在内存中,查找速度会更快。 -
@Neville - 我已经这样做了,它说状态还可以。
-
两个查询都使用不同的执行计划。所以,提示mysql使用索引dc.FKAEB144C64FA71464
-
@ajreal 谢谢,但是 dc 的主键不应该是查询的起点(第一次),我们想通过 ix_art_ref 开始减少行数,这应该从 3M 减少到 5k 行用于后续操作。
标签: mysql database performance