I am trying to speed a query that grabs data to be used to display a graph for a research project. It's currently VERY slow. It has 18295603
items only and takes about 20s
per query. Here is an example query:
SELECT `data_dylos`.`id`, `data_dylos`.`node_id`, `data_dylos`.`dylos_bin_1`,
`data_dylos`.`dylos_bin_2`, `data_dylos`.`dylos_bin_3`,
`data_dylos`.`dylos_bin_4`, `data_dylos`.`big_particles`,
`data_dylos`.`small_particles`, `data_dylos`.`added_on`,
`data_dylos`.`last_modified`, `data_dylos`.`reading_time` FROM `data_dylos`
WHERE (`data_dylos`.`added_on` > '2014-08-06 23:00:24' AND
`data_dylos`.`node_id` = 3 ) LIMIT 21
The added_on value is calculated before the call is made.
Here is my show create table data_dylos
:
CREATE TABLE `data_dylos` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`node_id` int(11) NOT NULL,
`dylos_bin_1` int(11) DEFAULT NULL,
`dylos_bin_2` int(11) DEFAULT NULL,
`dylos_bin_3` int(11) DEFAULT NULL,
`dylos_bin_4` int(11) DEFAULT NULL,
`reading_time` datetime DEFAULT NULL,
`added_on` datetime NOT NULL,
`last_modified` datetime NOT NULL,
`big_particles` int(11) DEFAULT NULL,
`small_particles` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `data_dylos_1eac40ef` (`node_id`),
KEY `data_dylos_aa73cdcc` (`added_on`)
) ENGINE=InnoDB AUTO_INCREMENT=20029122 DEFAULT CHARSET=latin1
The fields of interest ARE already indexed but it is still very slow.
Any help will be greatly appreciated.
Thanks!
Best Answer
This is as you say a very simple query, so the optimal index here is very clear. Thanks for showing the whole table structure, indexes and full query, not all people do that.
You indexes are in the good direction, but you must know that (in general, there are other query plans like
index_merge
) a table scan can only use one index. In this case, as you are filtering by two columns, you have to add the multi-column index:You have to create it on that order
(node_id, added_on)
and not in reverse(added_on, node_id)
, as that would be a different index. The difference is that in aBTREE
index, after arange
join type is used, the rest of the index is useless.That is the optimal index query-wise. If you continue to have performance problems you may want to review your configuration (specially
innodb_buffer_pool_size
).There are additional techniques that may help you, like caching or partitioning, but those are more advanced, or may require more structure changes, so try this first.