Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MySQL, order by multiple columns from multiple tables

I have two tables:

Table of Artists (tbl_artist):

artist_id - primary key
artist_name - has index   


Table of Albums (tbl_album):

album_id - primary key
album_artist_id - foreign key, has index
album_name - has index too

Tables have a lot of records on production server (artists - 60k, albums - 250k).

And on index page there is a list of albums, with pagination step = 50. Albums are sorted by artist_name ASC, album_name ASC. So the simplified query is following:

SELECT *
FROM tbl_artist, tbl_album
WHERE album_artist_id = artist_id
ORDER BY artist_name, album_name
LIMIT 0, 50

Query is executing very long. Probably it's because of ordering by columns from different tables. When I leave only 1 ordering - query is executing immediately.

What is possible to do in such situation? Many thanks.

Edit: explain:

+----+-------------+---------------+--------+------------------+---------+---------+-----------------------------------+--------+---------------------------------+
| id | select_type | table         | type   | possible_keys    | key     | key_len | ref                               | rows   | Extra                           |
+----+-------------+---------------+--------+------------------+---------+---------+-----------------------------------+--------+---------------------------------+
|  1 | SIMPLE      | tbl_album     | ALL    | album_artist_id  | NULL    | NULL    | NULL                              | 254613 | Using temporary; Using filesort |
|  1 | SIMPLE      | tbl_artist    | eq_ref | PRIMARY          | PRIMARY | 4       | db.tbl_album.album_artist_id      |      1 |                                 |
+----+-------------+---------------+--------+------------------+---------+---------+-----------------------------------+--------+---------------------------------+

explain with STRAIGHT_JOIN

+----+-------------+---------------+------+-----------------+-----------------+---------+------------------------------------+-------+---------------------------------+
| id | select_type | table         | type | possible_keys   | key             | key_len | ref                                | rows  | Extra                           |
+----+-------------+---------------+------+-----------------+-----------------+---------+------------------------------------+-------+---------------------------------+
|  1 | SIMPLE      | tbl_artist    | ALL  | PRIMARY         | NULL            | NULL    | NULL                               | 57553 | Using temporary; Using filesort |
|  1 | SIMPLE      | tbl_album     | ref  | album_artist_id | album_artist_id | 4       | db.tbl_artist.artist_id            |     5 |                                 |
+----+-------------+---------------+------+-----------------+-----------------+---------+------------------------------------+-------+---------------------------------+
like image 495
kasitan Avatar asked May 25 '12 10:05

kasitan


People also ask

How do I sort multiple columns in MySQL?

Summary. Use the ORDER BY clause to sort the result set by one or more columns. Use the ASC option to sort the result set in ascending order and the DESC option to sort the result set in descending order. The ORDER BY clause is evaluated after the FROM and SELECT clauses.

Can we have 2 ORDER BY in MySQL?

Using with multiple columnsDefine your multiple column names in ORDER BY clause separated by a comma (,). You can also specify your sorting order ASC or DESC . In the above query, I am ordering the emp_salary table by age in Ascending order and salary by descending order.


2 Answers

You need an index of (artist_name, artist_id) and then (album_artist_id, album_name). The reason is because your join is between artist_id and album_artist_id, so it has to perform the same join with the indexes to produce a final need index of (artist_name, album_name) for the sort.

You then need to change your order by to be: ORDER BY artist_name, artist_id, album_name. This is because there could be two artist_name's that are the same, and this will cause it to order not as you are expecting. Also it will prevent it from using an index.

Using just indexes on artist_name, and album_name doesn't provide enough information to produce that sort, all you have is an ordered list of names with nothing to indicate how they connect to the other table.

like image 164
Joe Avatar answered Oct 11 '22 16:10

Joe


Try changing the index on (album_artist_id) to an index on (album_artist_id, album_name).

like image 27
Hammerite Avatar answered Oct 11 '22 18:10

Hammerite