Reputation: 8016
I have two tables:
CREATE TABLE `album` (
`album_id` int(10) unsigned NOT NULL,
`artist_id` int(10) unsigned NOT NULL,
`album_type_id` int(10) unsigned NOT NULL,
`name` varchar(255) NOT NULL,
`first_released` year(4) NOT NULL,
`country_id` smallint(5) unsigned DEFAULT NULL,
PRIMARY KEY (`album_id`),
KEY `artist_id` (`artist_id`),
KEY `name` (`name`)
) ENGINE=InnoDB
CREATE TABLE `artist` (
`artist_id` int(10) unsigned NOT NULL,
`type` enum('Band','Person','Unknown','Combination') NOT NULL,
`name` varchar(255) NOT NULL,
`gender` enum('Male','Female') DEFAULT NULL,
`founded` year(4) DEFAULT NULL,
`country_id` smallint(5) unsigned DEFAULT NULL,
PRIMARY KEY (`artist_id`),
KEY `name` (`name`)
) ENGINE=InnoDB;
My first query:
select ar.name, count(*)
from artist ar
join album al on ar.artist_id=al.artist_id
group by ar.artist_id
limit 10;
which produces a result set in 0.00 seconds.
I would like to order the results, so I add "order by 2 desc":
select ar.name, count(*)
from artist ar
join album al on ar.artist_id=al.artist_id
group by ar.artist_id
order by 2 desc
limit 10;
but now the result set takes over 5 seconds, which is too slow.
Execution plan:
How can I add an index to speed up my new query?
Sample data: http://bit.ly/1k5ROrT
Upvotes: 4
Views: 241
Reputation: 1539
First you should select and count with indexed column which will make better order by performance, then you can join artist name on the filtered result to complete your data. Something will like.
SELECT ar2.name, t.c
FROM
(
SELECT ar.artist_id, COUNT(*) c
FROM artist ar
JOIN album al ON ar.artist_id=al.artist_id
GROUP BY ar.artist_id
ORDER BY 2 DESC
LIMIT 10
)
t JOIN artist ar2 ON ar2.artist_id=t.artist_id
I try with your data and it take less than 1 sec. Hope this help
Upvotes: 2