MySQL在非常简单的SELECT查询上极其慢


10

我们有一个在虚拟机上运行的简单Web应用程序,它使用InnoDB引擎将其数据保存在MySQL 5.5数据库中。大约三年来,一切工作正常,但突然变得非常缓慢。

例如,我有一个非常简单的表,其中包含地址:

CREATE TABLE `addresses` (
  `address_id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(64) CHARACTER SET latin1 NOT NULL,
  `firstname` varchar(64) CHARACTER SET latin1 NOT NULL,
  `street` varchar(64) CHARACTER SET latin1 NOT NULL,
  `housenumber` varchar(16) CHARACTER SET latin1 NOT NULL,
  `zip` varchar(5) CHARACTER SET latin1 NOT NULL,
  `city` varchar(64) CHARACTER SET latin1 NOT NULL,
  `email` varchar(64) CHARACTER SET latin1 NOT NULL,
  `phone` varchar(16) CHARACTER SET latin1 NOT NULL,
  `birthdate` date NOT NULL,
  PRIMARY KEY (`address_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin

该表可容纳约800个条目,实际上并不多。但是运行查询

SELECT * FROM addresses

出于测试目的,它似乎永远无法完成。我使用服务器本身上的mysql CLI进行了检查:它输出表的某些行,然后等待很长时间,直到输出下一行。

因此,也许在数据发送阶段存在问题,但我不确定。

该虚拟机具有2GB的RAM,仅使用了320MB。CPU也以1%到2%的极低速度运行。mytop不显示任何其他阻止服务器的查询。IT管​​理员表示,他们在硬件方面没有做任何更改。

我已经尝试过诸如重新启动数据库服务器,重新启动虚拟机之类的操作。没有任何帮助。

编辑:

EXPLAIN SELECT * FROM addresses

给我这个结果:

+----+-------------+-----------+------+---------------+------+---------+------+------+-------+
| id | select_type | table     | type | possible_keys | key  | key_len | ref  | rows | Extra |
+----+-------------+-----------+------+---------------+------+---------+------+------+-------+
|  1 | SIMPLE      | addresses | ALL  | NULL          | NULL | NULL    | NULL |  793 |       |
+----+-------------+-----------+------+---------------+------+---------+------+------+-------+
1 row in set (0.00 sec)

虚拟盒子,Xen还是其他?主机磁盘如何设置?同一盒中是否还有其他VM运行缓慢?回答这些问题可能会揭示答案
Matt

我不是管理程序的所有者,因此我无法真正回答。我已经问过虚拟机管理程序的管理员是否知道最近的任何更改,但他说不。
tabb

如果可以,请关闭mysql并运行一些磁盘和内存基准测试。不必太复杂。这样做的目的是隔离是否是mysql的问题,也许是下面答案中指出的索引问题,或者是更广泛的问题。
马特

好点,我经历过它可能不是mysql问题。运行mysql -u username -ppassword mydb -e 'SELECT * FROM addresses输出缓慢,但是附加`> test.txt`,它运行非常快。现在这可能是一个不同的问题!?我如何对此进行调查?
tabb

请与系统管理程序的所有者联系,并要求他们检查日志中是否有任何错误。特别是磁盘错误。告诉他你的症状。立即备份。
马特

Answers:


13

如果cpu负载较低,则表明缺少索引没有问题,如果是这种情况,查询将只需要占用更多cpu和磁盘访问权限。您还说它工作了3年。

您是否检查了一般的磁盘访问速度(特别是在数据库所在的分区上)?例如使用dd 像这里。您所描述的内容听起来像是死磁盘或半死角袭击。我希望备份吗?


那是个很好的观点。可能就像主机上的磁盘错误一样简单。
马特

9

您可以尝试几件事,

  1. 你有索引设置吗?

索引使快速查找记录成为可能,而无需先进行全表扫描,从而大大减少了执行时间。

CREATE INDEX idx_name ON addresses(name);
  1. 在运行查询之前,请先使用EXPLAIN关键字,

在SELECT查询之前使用时,它将描述MySQL如何打算执行查询以及在完成之前需要处理的行数。

  1. 如果它的VM增加了RAM,请对mysql.ini进行一些更改,并配置mysql.ini以查看性能是否提高。

有很多MySQL优化器可以指导您。

帮助这有帮助


好的,但是在很小的表(<800行)上创建索引似乎没有我需要的帮助。完成上面引用的查询需要一分钟以上的时间。如此小的表的全表扫描不应该花那么长时间。
tabb

所以...您添加索引了吗?如果您不确定问题出在哪里,那我会从基础开始,然后逐步解决。如果正确完成,添加索引只会提高性能。
安东尼·佛尼托

是的,我在名称列上添加了索引。但是我上面的查询甚至没有任何限制WHERE子句,因此它必须读取整个表并打印出来。添加索引没有帮助。
tabb

我在上面添加了EXPLAIN查询的结果。在我看来,这很好,但是性能仍然很低。我不是虚拟化管理器的管理员,所以无法增加RAM。但是htop表明2050MB RAM中仅使用了307MB。
tabb

关于索引,您确实需要考虑要索引的列,您不希望仅对所有列进行索引,对数量最大的列进行索引,我对此做出了一些疯狂的假设,但我将从 name“ firstname”开始。其次,您确定索引正确吗?可能的键:NULL如果列为NULL,则表明找不到相关的索引。
Anthony Fornito '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.