MySQL,按多个表中的多列排序

kas*_*tan 5 mysql join sql-order-by

我有两个表:

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
Run Code Online (Sandbox Code Playgroud)

表在生产服务器上有很多记录(艺术家 - 60k,专辑 - 250k)。

并且在索引页面上有一个专辑列表,分页步长= 50。专辑按artist_name ASC、album_name ASC 排序。所以简化的查询如下:

SELECT *
FROM tbl_artist, tbl_album
WHERE album_artist_id = artist_id
ORDER BY artist_name, album_name
LIMIT 0, 50
Run Code Online (Sandbox Code Playgroud)

查询执行时间很长。可能是因为按不同表中的列排序。当我只留下 1 个排序时 - 查询立即执行。

在这种情况下可以做什么?非常感谢。

编辑:解释:

+----+-------------+---------------+--------+------------------+---------+---------+-----------------------------------+--------+---------------------------------+
| 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 |                                 |
+----+-------------+---------------+--------+------------------+---------+---------+-----------------------------------+--------+---------------------------------+
Run Code Online (Sandbox Code Playgroud)

用 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 |                                 |
+----+-------------+---------------+------+-----------------+-----------------+---------+------------------------------------+-------+---------------------------------+
Run Code Online (Sandbox Code Playgroud)

小智 5

您需要一个索引 ( artist_name, artist_id),然后是 ( album_artist_id, album_name)。原因是因为您的连接位于artist_id和 之间album_artist_id,因此它必须与索引执行相同的连接以生成最终需要的索引 ( artist_name, album_name) 进行排序。

然后,您需要将订单更改为:ORDER BY artist_name, artist_id, album_name。这是因为可能有两个artist_name相同的 ' ,这将导致它的顺序不符合您的预期。它还会阻止它使用索引。

仅使用 上的索引artist_name,并且album_name不能提供足够的信息来生成该排序,您所拥有的只是一个有序的名称列表,没有任何内容表明它们如何连接到另一个表。


jue*_*n d 0

在您的列上添加索引order by

如果您想知道为什么查询需要这么长时间,请查看 EXPLAIN. 例子:

explain select * from your_table order by col1, col2
Run Code Online (Sandbox Code Playgroud)