MySQL慢查询尽管EXPLAIN显示较少的行

时间:2015-03-13 10:54:50

标签: mysql innodb

我使用的是MySQL 5.1.34,所有表都在Innodb Engine中。

我有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个匹配" date"在表A中。 " date"列被索引,一个简单的WHERE子句可以在第二个内完成。 E.g。

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命令解决缓慢问题,输出如下。

enter image description here

可能是什么原因?请帮忙!

2 个答案:

答案 0 :(得分:0)

正如我所说,这可能是寻求问题的磁盘。当您测量时,一旦记录在内存中,查询就会很快,这对我来说就证实了这个问题。

从磁盘获取随机位置大约需要10毫秒,因为磁盘头必须移动。相关记录可能集群在磁盘上,服务器必须做大约。 20s / 10ms = 20.000寻求。

这是一些显而易见的方法:

  • 使用SSD。没有寻求。
  • 为服务器添加足够的RAM以避免磁盘访问,或者使用专用服务器进行这些查询(16GB看起来绰绰有余(虽然我不知道记录的大小)所以我猜其他常用的大规模的表格。
  • 按日期缓存结果 - 并将其存储在数据库中(memcached / redis / ..)。如果记录对于旧日期是静态的,则可以很好地工作,因为您不必担心缓存失效。

无论如何,做一些背后的计算并计算内存需求可能是个好主意。

答案 1 :(得分:0)

由于未提供SHOW CREATE TABLE,您遗漏了很多重要信息,但我会做出一些猜测。

你真的拿10K行吗?你打算和他们一起做什么?获得那么多行需要时间。

如果您使用的是MyISAM,那么B将从INDEX(ID, TableC_ID)中受益匪浅。 InnoDB不应该从中受益,除非该表非常宽泛。

SHOW VARIABLES LIKE '%buffer%';你有多少内存?

是否正在使用查询缓存?如果是,那就可以解释为什么它第二次如此之快。大多数生产系统都认为关闭QC会更好。