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

标签 mysql innodb

我正在使用 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 个匹配表 A 中“日期”的表。 “日期”列被索引,一个简单的 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 命令解决运行缓慢的问题,输出如下。

enter image description here

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

最佳答案

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

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

有几个明显的方法:

  • 使用固态硬盘。没有寻求。
  • 向服务器添加足够的 RAM 以避免磁盘访问,或者为这些查询使用专用服务器(16GB 看起来绰绰有余(虽然我不知道记录的大小)所以我想还有其他经常使用的巨大的 table )。
  • 缓存每个日期的结果 - 并将其存储在数据库中(memcached/redis/..)。如果旧日期的记录是静态的,这可能会非常有效,因为您不必担心缓存失效。

无论如何,做一些粗略计算并弄清楚内存需求可能是个好主意。

关于尽管 EXPLAIN 显示较少的行,但 MySQL 慢查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29030416/

相关文章:

mysql - 左连接查询需要永远执行

mysql - 放弃写入 InnoDB

mysql - 如何让 MySQL innoDB 支持新的 unicode 字符集,比如 '\U0001f3b8'

mysql - SQL 错误 : Row size too large for VARCHAR(20)

mysql - 为什么 information_schema.INNODB_LOCKS 的 'lock_type' 总是 RECORD?

mysql - RAND() 查询和性能

mysql - 在 MySQL 表中查找 "exotic"值

javascript - 使用另存为对话框将 HTML 表格数据导出到 Excel (JQuery)

mysql - MySQL Workbench 中的 MySQL WITH ROLLUP 查询语法错误?

php - 如果语句在预期工作时未被执行