I'm working on a mysql table with roughly 4 million message entries and I'm trying to select the latest 50 messages based on a timestamp.
An additional requirement is that the returned messages do not start with a fixed prefix.
The problem is that a single query is taking roughly 25% cpu and takes around up to 1.5 seconds. The query is done frequently by multiple clients and is causing performance issues on our 8 core db-server.
SELECT * FROM largeTable
WHERE msg NOT LIKE 'myPrefix%'
ORDER BY timestamp DESC LIMIT 0, 50;
I tried profiling with the builtin mysql profiler, here's the result for the query:
+----------------------+----------+
| Status | Duration |
+----------------------+----------+
| starting | 0.000044 |
| checking permissions | 0.000004 |
| Opening tables | 0.000010 |
| init | 0.000019 |
| System lock | 0.000005 |
| optimizing | 0.000005 |
| statistics | 0.000007 |
| preparing | 0.000007 |
| Sorting result | 0.000002 |
| executing | 0.000002 |
| Sending data | 0.000006 |
| Creating sort index | 0.788023 |
| end | 0.000009 |
| query end | 0.000003 |
| closing tables | 0.000009 |
| freeing items | 0.000012 |
| cleaning up | 0.000010 |
+----------------------+----------+
I first thought that maybe the problem is that it checks the prefix for all entries but after the profiling .
| Creating sort index | 0.788023 |
Seems to be the culprit. So the ORDER BY Clause? How can i speed this up? Is there some type of index i can build to fix this? New messages are added approximately every few seconds, while queries happen a more often.
Thanks for your help!
Edit: Thanks for the comments, here's the info requested.
The database is not being created and filled by my code but by some external python service. I didn't add any indexes yet.
Explain output:
id:1
select_type:SIMPLE
table:largeTable
type:ALL
possible_keys:NULL
key: NULL
key_len:NULL
ref: NULL
rows: 3492633
Extra: Using where; Using filesort
Table Structure:
CREATE TABLE `largeTable` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`timestamp` int(10) unsigned NOT NULL,
`client_id` int(11) unsigned NOT NULL,
`name` varchar(32) NOT NULL,
`msg` varchar(528) NOT NULL,
`target_id` int(11) unsigned DEFAULT NULL,
`target_name` varchar(32) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `client` (`client_id`)
) ENGINE=MyISAM AUTO_INCREMENT=4013829 DEFAULT CHARSET=utf8 |