尽管 EXPLAIN 显示较少的行,但 MySQL 慢查询
Posted
技术标签:
【中文标题】尽管 EXPLAIN 显示较少的行,但 MySQL 慢查询【英文标题】:MySQL Slow Query despite EXPLAIN shows less rows 【发布时间】:2015-03-13 10:54:50 【问题描述】:我使用的是 mysql 5.1.34,所有表都在 Innodb 引擎中。
我有 3 个表如下:
TableA (1M rows)
-ID (Auto Increment PK)
-TableB_ID
-Date varchar(indexed)
-Other Fields
TableB (60M rows)
-ID (Auto Increment PK)
-TableC_ID
-Other Fields
TableC (10M rows)
-ID (Auto Increment PK)
-Other Fields
我的目标是加入 3 个与 TableA 中的“日期”匹配的表。 “日期”列被索引,一个简单的 WHERE 子句可以在一秒钟内完成。例如
SELECT * FROM TableA where date = '2015-03-13';
10000 rows in set (0.1 sec)
但是,当我尝试使用下面的 SQL 连接 TableB 和 TableC 时,过程变得非常缓慢。
SELECT A.*, C.Something FROM TableA A JOIN TableB B on A.TableB_ID = B.ID JOIN TableC C on B.TableC_ID = C.ID WHERE A.date = '2015-03-13';
10000 rows in set (20 sec)
我尝试使用 EXPLAIN 命令解决缓慢问题,输出如下。
可能是什么原因?请帮忙!
【问题讨论】:
A.TableB_ID
和 B.TableC_ID
是否已编入索引?
@AbhikChakraborty 已编辑。抱歉,是的,A.TableB_ID 和 B.TableC_ID 都已编入索引。
@KarolyHorvath 磁盘搜索是什么意思?
@AbhikChakraborty 。 . . B
和 C
中的 id
列是主键,正如 OP 所说和 explain
中所示。不需要额外的索引。
@PeirHwa.Soo 。 . .第二次运行查询需要多长时间?您可能遇到冷缓存问题,将大约 20,000 页从磁盘读取到内存需要时间。
【参考方案1】:
正如我所说,这可能是磁盘查找问题。正如您所测量的,一旦记录在内存中,查询速度很快,对我来说,这证实了问题。
从磁盘中获取随机位置大约需要 10 毫秒,因为磁盘磁头必须移动。相关记录可能聚集在磁盘上,服务器必须做大约。 20 秒/10 毫秒 = 20.000 次搜索。
有几个明显的方法:
使用 SSD。不求。 为服务器添加足够的 RAM 以避免磁盘访问,或者为这些查询使用专用服务器(16GB 看起来绰绰有余(虽然我不知道记录的大小)所以我猜还有其他常用的巨大的桌子)。 按日期缓存结果 - 并将其存储在数据库中 (memcached/redis/..)。如果旧日期的记录是静态的,这可能会非常有效,因为您不必担心缓存失效。无论如何,做一些粗略的计算并弄清楚内存需求可能是个好主意。
【讨论】:
【参考方案2】:你没有提供SHOW CREATE TABLE
,漏掉了很多重要信息,但我会做一些猜测。
您真的在获取 10K 行吗?你打算怎么处理他们所有人?获取这么多行需要时间。
如果您使用的是 MyISAM,那么 B 将从 INDEX(ID, TableC_ID)
中受益匪浅。 InnoDB 不应该从中受益,除非表非常“宽”。
SHOW VARIABLES LIKE '%buffer%';
你有多少内存?
查询缓存是否正在使用中?如果是这样,那就可以解释为什么第二次这么快了。大多数生产系统都认为关闭 QC 会更好。
【讨论】:
以上是关于尽管 EXPLAIN 显示较少的行,但 MySQL 慢查询的主要内容,如果未能解决你的问题,请参考以下文章