很慢 SQL ORDER BY, EXPLAIN 不解释

Very slow SQL ORDER BY, and EXPLAIN doesn't explain

查询:

SELECT
    m.*,
    mic.*
FROM
    members m,
    members_in_class_activities mic
WHERE
    m.id = mic.member_id AND
    mic.not_cancelled = '1' AND
    mic.class_activity_id = '32' AND
    mic.date = '2016-02-14' AND
    mic.time = '11:00:00'
ORDER BY
    mic.reservation_order

Table members 有大约 10 万条记录,而 table members_in_class_activities 有大约 30 万条记录。结果集只有 2 条记录。 (不是 2k,只是 2。)

所有相关列都已编入索引(idreservation_order 是主要列):member_id, not_cancelled, class_activity_id, date, time.

还有 class_activity_id + member_id + date + time + not_cancelled 的唯一键。 not_cancelledNULL'1'

所有其他查询都非常快(1-5 毫秒),但这个非常慢:600-1000 毫秒。

什么没有帮助:

有什么帮助,非常大:

我只有两个问题:

  1. 什么????
  2. 如何让我仍然ORDER BY x,但又让它变快?我真的需要一个单独的专栏吗?

我在我的开发机器上 运行 10.1.9-MariaDB,但在生产机器上 MySQL 5.5.27-log 也很慢。

不要在您的主查询中使用 order by。试试这个:

SELECT * FROM (   
  ... your query
) ORDER BY mic.reservation_order

正如您提到的 members_in_class_activities has about 300k 条记录,因此您的排序将适用于所有 300k 条记录,这肯定会减慢您的查询速度。

class_activity_id + member_id + date + time + not_cancelled -- 不是最优的。

以任意顺序从 WHERE 中的“=”字段开始,然后在 ORDER BY 字段中添加:

INDEX(class_activity_id, date, time, not_cancelled,
      reservation_order)

既然你似乎需要 UNIQUE 约束,那么通过将 member_id 放在末尾(它将是 'out of the way' 来调整你的索引几乎一样好但未使用):

UNIQUE(class_activity_id, date, time, not_cancelled, member_id)

一般来说,把datetime分开是不好的;为该对建议一个 DATETIME 列。

Cookbook on creating indexes.