简单的mysql查询需要16秒以上

时间:2014-01-02 09:35:49

标签: mysql

简单的SQL查询需要16秒加。这是表格。

CREATE TABLE IF NOT EXISTS `udr` (
  `userid` int(11) NOT NULL DEFAULT '0',
  `time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `upbytes` int(11) NOT NULL DEFAULT '0',
  `downbytes` int(11) NOT NULL DEFAULT '0',
  `traffictype` int(11) NOT NULL DEFAULT '1',
  KEY `userid` (`userid`),
  KEY `time` (`time`),
  KEY `traffictype` (`traffictype`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

有1600万条记录。 (原来有1.41亿,我修剪看是否是问题)

有问题的查询是(像)

select time,upbytes,downbytes
 from udr
  where userid = 315533 and 
        time between '2014-01-01 14:35:28' and '2014-01-02 14:35:28'

我认为问题是时间部分,所以我删除了时间条件并尝试了

select time,upbytes,downbytes from udr where userid = 315533
...
10282 rows in set (19.42 sec)

查询仍需要16秒钟。

这是我的关键配置参数

key_buffer    = 32M
max_allowed_packet  = 16M
thread_stack    = 192K
thread_cache_size       = 8
query_cache_limit = 1M
query_cache_size        = 16M

对这一个没有想法。

由于

mysql> explain select * from udr where userid = '315533';
+----+-------------+-------+------+---------------+--------+---------+-------+-------+-------+
| id | select_type | table | type | possible_keys | key    | key_len | ref   | rows  | Extra |
+----+-------------+-------+------+---------------+--------+---------+-------+-------+-------+
|  1 | SIMPLE      | udr   | ref  | userid        | userid | 4       | const | 12738 |       |
+----+-------------+-------+------+---------------+--------+---------+-------+-------+-------+
1 row in set (0.02 sec)

iotop报道重磁盘io。我怀疑mysql正在检索所有记录到内存。

3 个答案:

答案 0 :(得分:3)

SELECT time,upbytes,downbytes
    FROM udr
    WHERE userid = 315533 AND
    time BETWEEN '2014-01-01 14:35:28' AND '2014-01-02 14:35:28'

在此查询中,您要搜索两列timeuserid。您确实在这两列上都有索引,但MySQL一次只能使用其中一个。

MySQL将选择使用time - 索引或userid索引。如果选择userid,则必须检索12738行,这会导致查询时间过长。然后,MySQL将搜索检索到的数据,以过滤掉time - 列。

解决方案是在两个列上添加索引:

ALTER TABLE udr ADD KEY (`userid`, `time`);

这样,MySQL可以在useridtime上进行搜索,而无需先检索数据。

注意:创建新索引可能需要几分钟时间,请耐心等待。

答案 1 :(得分:0)

尝试在timeuserid中建立索引。您可以使用phpmyadmin或sqlyog轻松构建索引。

答案 2 :(得分:0)

  

但是仅使用userid的查询仍然占用了几乎相同的数量   时间。

你不能做得更多。 你的硬件规格是什么? 我的配置是平均值,高于你的配置:

query_cache_size =  64 MiB
key_buffer =  128 MiB
max_allowed_packet  =  16M
thread_stack    =  294 Kb
thread_cache_size       = 128
query_cache_limit =  128 KiB

我建议使用MariaDB / Percona而不是标准MySQL,然后再试用MYISAM。他们对Aria有很大的改善......