mysql花费太长时间发送数据


9

我有一个简单的表,其中包含数百万个记录(14,000,000),而对于一个简单的查询,它花费了太多的时间“发送数据”。

桌子

CREATE TABLE IF NOT EXISTS details (
  id int(11) NOT NULL,
  date date NOT NULL,
  time int(2) NOT NULL,
  minutes_online decimal(5,0) NOT NULL,
  minutes_playing decimal(5,0) NOT NULL,
  minutes_chatting decimal(5,0) NOT NULL,
  minutes_away decimal(5,0) NOT NULL
  PRIMARY KEY (id,date,time)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;

简单查询

mysql> SELECT * FROM details WHERE id = 3014595;

说明

mysql> EXPLAIN SELECT * FROM details WHERE id = 3014595;
+----+-------------+-----------+------+---------------+---------+---------+-------+------+-------+
| id | select_type | table     | type | possible_keys | key     | key_len | ref   | rows | Extra |
+----+-------------+-----------+------+---------------+---------+---------+-------+------+-------+
|  1 | SIMPLE      | details   | ref  | PRIMARY       | PRIMARY | 4       | const | 1482 |       |
+----+-------------+-----------+------+---------------+---------+---------+-------+------+-------+

查询配置文件

mysql> SHOW PROFILE FOR QUERY 1;
+--------------------------------+----------+
| Status                         | Duration |
+--------------------------------+----------+
| starting                       | 0.000024 |
| checking query cache for query | 0.000078 |
| checking permissions           | 0.000014 |
| Opening tables                 | 0.000126 |
| System lock                    | 0.000011 |
| Table lock                     | 0.000030 |
| init                           | 0.000027 |
| optimizing                     | 0.000117 |
| statistics                     | 0.040077 |
| preparing                      | 0.000029 |
| executing                      | 0.000006 |
| Sending data                   | 7.536960 |
| end                            | 0.000013 |
| query end                      | 0.000004 |
| freeing items                  | 0.000037 |
| storing result in query cache  | 0.000006 |
| logging slow query             | 0.000003 |
| cleaning up                    | 0.000006 |
+--------------------------------+----------+

如您所见,该SELECT语句使用索引,并且仅读取1482行。但是,查询花费了7.536960秒发送数据。就像查询读取了更多所需的行一样。

这是一个简单的查询,只有7个字段(行平均59字节),没有花哨功能。知道是什么原因造成的吗?

注意:id是用户ID。每个用户每天的每一小时可能至少有一个条目。因此,id不是唯一的。

编辑:我有另一个表具有相同的结构和更多的行(3400万)。如果在此较大的表上运行相同的查询,它将在不到1秒的时间内返回结果。

唯一的区别是,较大的表所获得的查询不如较小的表那么多。

  • 查询数量是否有可能减慢该过程?MySQL缓存已打开。我还使用CakePHP缓存查询以减少查询数量。
  • 保存表的文件是否可能已损坏?

更新 通过将数据层与Web层分离,解决了该问题。数据层也在RAM上进行了升级,并在raid10上运行。


SELECT返回多少行?
hjpotter92

1591 rows in set (16.48 sec)我再次运行查询,这就是为什么持续时间不同的原因。现在花了16秒(!!)
rlcabral 2012年

而不是使用*尝试使用列,然后看看有什么区别
Muhammad Raheel 2012年

不。结果相同。
rlcabral 2012年

尝试使ID列成为简单的主索引。由于ID应该是唯一字段,因此您不需要使用它进行复杂的索引。这应该使您可以像光速一样快速地通过主键进行搜索。
亚历山大·普拉夫丁

Answers:


1

对于那些偶然发现这个问题并想知道的人,即使没有升级RAM,为什么发送数据花费的时间却更长。这是因为发送数据实际上包括搜索要发送的数据的时间。

https://dev.mysql.com/doc/refman/5.7/zh-CN/general-thread-states.html

线程正在读取和处理SELECT语句的行,并将数据发送到客户端。因为在此状态期间发生的操作往往会执行大量磁盘访问(读取),所以它通常是给定查询生命周期中运行时间最长的状态。


-2

尝试使用优化表表名优化表并检查状态。

需要做的大改变:

Alter table tablename engine = 'INNODB'

这将对您有很大帮助,并且表中可能应该有一个主键,但是您添加了三列作为主键。


-3

为ID创建单独的索引:

更改表详细信息添加键d1(id);

要使该索引生效,请重新启动MySQL或

分析表格细节;

如果可能,您还可以将数据库更改为InnoDB,以获取事务支持和其他好处。


这将有什么帮助?
Colin't Hart
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.