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 |