非常慢的SQL ORDER BY,并且EXPLAIN没有解释

时间:2016-02-14 16:46:11

标签: mysql sql-order-by mariadb

查询:

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

members有~100k记录,表members_in_class_activities有约300k。结果集只有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毫秒。

什么不起作用:

  • 仅选择2个主键而不是*(0%更改)
  • 一个真正的JOIN而不是一个隐式联接(它实际上似乎稍慢,但可能不是)(0%更改)
  • 将联接移至members完全使稍微更快(15%更改)

有什么帮助,非常:

  • 删除主键上的ORDER BY(99%更改)

我只有两个问题:

  1. 什么????
  2. 我如何ORDER BY x,但也要快点?我真的需要一个单独的专栏吗?
  3. 我在我的开发计算机上运行10.1.9-MariaDB,但生产的MySQL 5.5.27-log也很慢。

2 个答案:

答案 0 :(得分:3)

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

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

正如您所提到的那样members_in_class_activities has about 300k记录,因此您的订单将适用于所有 300k 记录,这些记录肯定会降低您的查询速度。

答案 1 :(得分:0)

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放在最后(它会'不在路上',但是将您的索引洗牌几乎一样好,但是没用过):

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

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

Cookbook on creating indexes