Reputation: 75
Simple sql query taking 16 seconds plus. Here is the table.
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;
There are 16 million records. (Originally there were 141 million, I pruned to see if it was the problem)
Query in question is (like)
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'
I thought the problem was the time part so I removed the time condition and tried following
select time,upbytes,downbytes from udr where userid = 315533
...
10282 rows in set (19.42 sec)
Still the query is taking 16 seconds plus.
Here is my key config params
key_buffer = 32M
max_allowed_packet = 16M
thread_stack = 192K
thread_cache_size = 8
query_cache_limit = 1M
query_cache_size = 16M
ran out of ideas on this one.
Thanks
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 reports heavy disk io. I suspect mysql is retrieving all records to memory.
Upvotes: 4
Views: 339
Reputation: 1877
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'
In this query, you are searching on two columns, time
and userid
. You do have indexes on both these columns, but MySQL can only use one of them at a time.
MySQL will choose to use either the time
-index or the userid
index. If it chooses userid
, 12738 rows will have to be retrieved, which causes the long query time. MySQL will then search through the retrieved data to filter out the time
-column.
The solution is to add a index on both the columns:
ALTER TABLE udr ADD KEY (`userid`, `time`);
This way MySQL can search on both userid
and time
without retrieving data first.
NOTE: It can take a few minutes to create the new index, be patient.
Upvotes: 3
Reputation: 32260
But the query only with userid was still taking almost same amount of time.
You can't do much more. What are your hardware specs? My configs are average and higher than yours:
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
I suggest to use MariaDB / Percona instead of standard MySQL and try again with MYISAM. They improved very much with Aria...
Upvotes: 0
Reputation: 187
Try to make indexing in time
and userid
.you can easily built index using phpmyadmin or sqlyog.
Upvotes: 0