我有两张桌子:
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
表格在制作服务器上有很多记录(艺术家 - 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
查询执行时间很长。可能是因为按不同表格的列排序。当我只留下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 | |
+----+-------------+---------------+--------+------------------+---------+---------+-----------------------------------+--------+---------------------------------+
用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 | |
+----+-------------+---------------+------+-----------------+-----------------+---------+------------------------------------+-------+---------------------------------+
答案 0 :(得分:1)
尝试将(album_artist_id)
上的索引更改为(album_artist_id, album_name)
上的索引。
答案 1 :(得分:1)
您需要(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
上的索引并不能提供足够的信息来生成那种排序,你所拥有的只是一个有序的名称列表,没有任何东西可以指示它们如何连接到另一个表
答案 2 :(得分:0)
在order by
。
如果您想知道为什么查询需要这么长时间,请查看EXPLAIN
。例如:
explain select * from your_table order by col1, col2
答案 3 :(得分:0)
在您排序的列上添加索引将是一个公平的呼喊。它是,是的,在服务器中占用更多空间,但执行将是最好的。阅读有关索引的更多信息:http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html或http://www.tizag.com/mysqlTutorial/mysql-index.php
答案 4 :(得分:0)
要注意的主要事项是,如果按列排序索引没有完整的where子句,则需要扫描多少行来解析排序依据。如果只检查50行 10行结果集你的形状不错,但如果它是5000,你可能需要重新考虑你的索引。
你能做的第二件事就是增加 sort_buffer_size 大