【问题标题】:MySQL, order by multiple columns from multiple tablesMySQL,按多个表中的多个列排序
【发布时间】:2012-05-31 22:51:53
【问题描述】:

我有两张桌子:

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 |                                 |
+----+-------------+---------------+------+-----------------+-----------------+---------+------------------------------------+-------+---------------------------------+

【问题讨论】:

  • 你能告诉我们mysql用“EXPLAIN SELECT...”告诉你什么吗?
  • 您是否尝试过将 Hammerite 的答案与您的 Straight_join 结合使用?在我看来,这应该很快。顺便说一句,你说的很长是什么意思?秒?几十秒?分钟?
  • @Argeman ,是的,我已经尝试过使用 straight_join 并且没有 - 没有增加速度,并且解释没有改变。很长,我的意思是 10-15 秒,上面的查询。以及 20-30 与真正的查询(与其他联接)。
  • 好的,这很慢。唯一剩下的就是尽量避免从第一个表中读取这么多行。他们可能都加入了第二个,所以也许一个返回 10 个加入专辑表的艺术家的子查询可能是一个解决方案?
  • 但是在网站上用户可以选择范围(简单分页)[0-50],或[1000-1050]甚至[20150-20200]。当然,艺术家拥有的专辑数量可以从 0 到 ...。我认为很难保证选择正确的艺术家范围。

标签: mysql join sql-order-by


【解决方案1】:

您需要 (artist_name, artist_id) 和 (album_artist_id, album_name) 的索引。原因是因为您的联接位于artist_idalbum_artist_id 之间,因此它必须对索引执行相同的联接才能生成排序的最终需求索引(artist_name,album_name)。

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

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

【讨论】:

  • 我已经尝试过类似的设置,但 MySQL 仍在使用文件排序 ...
【解决方案2】:

要注意的主要事项是,如果您没有完整的由 index 按列解析的 where 子句,则需要扫描多少行才能解析 order by。如果只检查 50 行以提供 10 行结果集你的状态还不错,但如果是 5000 行,你可能需要重新考虑你的索引。

你可以做的第二件事,就是增加sort_buffer_size

【讨论】:

【解决方案3】:

尝试将(album_artist_id) 上的索引更改为(album_artist_id, album_name) 上的索引。

【讨论】:

  • 这让我很惊讶。我不确定该建议什么。抱歉,我无法提供更多帮助。
【解决方案4】:

在您排序的列上添加索引将是一个公平的喊叫。是的,它会在服务器中占用更多空间,但执行将是最好的。阅读有关索引的更多信息:http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.htmlhttp://www.tizag.com/mysqlTutorial/mysql-index.php

【讨论】:

    【解决方案5】:

    order by 的列上添加索引。

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

    explain select * from your_table order by col1, col2
    

    【讨论】:

      猜你喜欢
      • 2018-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-11
      • 1970-01-01
      • 2022-10-04
      • 1970-01-01
      相关资源
      最近更新 更多